Spring 依赖注入

一、三大基础注入方式

1. 构造器注入(官方推荐首选)

复制代码
@Service
public class XxxService {
    private final XxxDao xxxDao;
    // 强制注入,依赖不可为空
    public XxxService(XxxDao xxxDao) {
        this.xxxDao = xxxDao;
    }
}
  • 优点:支持final、强制依赖、减少空指针、缓解循环依赖
  • 适用:项目核心必选依赖

2. Setter 设值注入

复制代码
@Service
public class XxxService {
    private XxxDao xxxDao;
    @Autowired
    public void setXxxDao(XxxDao xxxDao) {
        this.xxxDao = xxxDao;
    }
}
  • 优点:灵活,容器初始化后可动态修改依赖
  • 适用:非必需、可选依赖

3. 字段注入(不推荐生产使用)

复制代码
@Service
public class XxxService {
    @Autowired
    private XxxDao xxxDao;
}
  • 缺点:不能用 final、隐藏依赖、脱离 Spring 难以单元测试、更容易循环依赖

二、配套注入注解

1. @Autowired(Spring 原生,核心注入注解)

  • 默认按类型匹配 Bean;
  • 多个同类型 Bean 会报NoUniqueBeanDefinitionException歧义异常;
  • 可作用于构造、set 方法、成员变量。

2. @Qualifier(@Autowired 配套限定注解,非独立注入方式)

作用:同接口多实现时,指定 Bean 名称精准匹配,解决注入冲突。 使用位置:构造参数、set 参数、成员变量上方

复制代码
// 多实现场景
@Autowired
@Qualifier("mysqlUserDao")
private UserDao userDao;

3. @Primary(@Qualifier 替代方案)

在其中一个实现类添加,Spring 自动优先注入该 Bean,只能设置一个主 Bean,灵活性差。

复制代码
@Repository
@Primary
public class MysqlUserDao implements UserDao {}

4. @Resource(JSR-250 规范)

  • 优先按 Bean 名称匹配,无需搭配@Qualifier

  • 不支持构造方法注入。

    @Resource(name = "mysqlUserDao")
    private UserDao userDao;

5. @Inject(JSR-330 规范)

功能近似@Autowired,无required属性,需额外引入依赖,项目极少使用。

6. @Value(普通值注入)

注入字面量、配置文件属性(简单类型,非对象 Bean 注入)

复制代码
@Value("${server.port}")
private Integer port;

三、集合批量注入

同类型所有 Bean 可直接注入到集合 / 数组,无需@Qualifier

复制代码
@Autowired
private List<UserDao> daoList;

四、三种注入方式对比

注入方式 优点 缺点 推荐度
构造器注入 依赖不可为空、线程安全、易测试、循环依赖少 可选依赖需重载构造 ⭐⭐⭐⭐⭐ 生产首选
Setter 注入 可动态修改依赖,适配可选依赖 实例创建后赋值,存在空指针风险 ⭐⭐⭐ 仅可选依赖使用
字段注入 代码简洁、书写少 无法 final、难单元测试、隐藏依赖 ⭐ 不推荐

五、总结

  • 注入方式只有三类:构造注入、set 注入、字段注入;
  • @Autowired/@Resource/@Inject实现注入的注解
  • @Qualifier/@Primary辅助限定注解,用来解决多 Bean 冲突,不属于注入方式;
  • @Value专门注入普通配置值,不用于对象 Bean 依赖注入。
相关推荐
带刺的坐椅1 小时前
多 Agent 协作实战:任务编排与子代理系统
java·ai·llm·agent·solon·harness
木木子222 小时前
# 星座配对深度解析:Select 长列表选择器、矩阵评分算法与数据驱动建议
java·算法·华为·矩阵·harmonyos
摇滚侠2 小时前
云原生 Java 架构师的第一课 K8s+Docker+KubeSphere+DevOps 51-60
java·云原生·kubernetes
折哥的程序人生 · 物流技术专研2 小时前
第4篇:模板方法 vs 策略模式,面试怎么选?
java·设计模式·策略模式·行为型模式·模版方法模式·扩充系列·继承v组合
吠品2 小时前
Mac定时关机、开机自动化:用shutdown和pmset就够了
android·java·开发语言
程序员爱钓鱼2 小时前
Cargo 包管理器详解:Rust 开发必会工具
后端·面试·rust
进击的程序猿~2 小时前
Go Zero源码阅读2
开发语言·后端·golang
hdsoft_huge2 小时前
JDK系列19:JVM全维度调优实战,内存、元空间、线程栈、GC参数压测调优完整方案
java·开发语言·jvm
曹牧2 小时前
Eclipse:SVN 回复
java·svn·eclipse