Skip to content

概念卡片:Spring 依赖注入与 IoC

一句话机制

IoC(控制反转)是「把创建对象、管理依赖的控制权从程序反转到容器」的思想,DI(依赖注入)是它的具体实现——容器创建 Bean 后,自动把被依赖对象注入调用者,调用者无需 new、无需主动获取。 这是 Spring 松耦合的根基。

IoC vs DI

  • IoC:控制反转,思想/原则(谁控制依赖的创建?由容器)
  • DI:依赖注入,实现手段(容器怎么把依赖给调用者)

类比:IoC 是「不要自己做饭,去食堂吃」的原则,DI 是「食堂把菜端到你桌上」的具体动作。

三种注入方式

方式机制特点
setter 注入无参构造创建后,调 setter 注入先创建再注入,可选依赖灵活
构造器注入调带参构造器直接注入创建即完成注入,依赖强制必需
字段注入反射直接赋值字段(@Autowired 字段)最简洁,但难测试、掩盖依赖

官方推荐:构造器注入为主(依赖必需、不可变、易测试),setter 注入用于可选依赖,避免字段注入(隐式依赖、难做单元测试)。

java
// 推荐:构造器注入
public class Chinese {
    private final Axe axe;               // final,不可变
    public Chinese(Axe axe) { this.axe = axe; }
}

// 不推荐:字段注入
public class Chinese {
    @Autowired
    private Axe axe;                     // 隐式依赖,测试难注入
}

@Autowired vs @Resource(面试高频)

维度@Autowired(Spring)@Resource(JSR-250)
提供方SpringJDK 标准(javax.annotation)
匹配顺序byType 优先,多个同类型再 byName(配 @Qualifier)byName 优先,找不到再 byType
是否必须默认必须(required=true),可 @Autowired(required=false)默认必须

关键区别一句话:@Autowired 按类型(byType)注入,@Resource 按名称(byName)注入。当接口有多个实现时,@Autowired 需配 @Qualifier 指定,@Resource 用 name 指定。

松耦合的本质

依赖接口而非实现类 + 容器注入:改变依赖实现(如 Axe 从 StoneAxe 换成 SteelAxe)只需改配置,调用者代码零改动。这就是「面向接口编程」+「依赖注入」带来的解耦收益。

常见误解(避坑)

  1. ❌ "IoC 和 DI 是一回事"。→ IoC 是思想,DI 是实现;还有 Service Locator 等其它 IoC 实现方式。
  2. ❌ "@Autowired 按名称注入"。→ 默认按类型(byType),只有多个同类型候选时才退化为按名称 + @Qualifier。
  3. ❌ "字段注入最方便,应该多用"。→ 字段注入依赖隐式、难测试、易造成循环依赖不可见,官方推荐构造器注入。
  4. ❌ "构造器注入和 setter 注入没区别"。→ setter 是先无参构造再注入(对象已创建、依赖可缺),构造器是创建即注入(依赖强必需)。

关联

  • 原始资料:✅【02】Spring核心机制:依赖注入
  • 容器机制:[Spring IOC容器初始化与循环依赖](./Spring IOC容器初始化与循环依赖)(refresh 12 步 + Bean 生命周期 + 三级缓存)
  • 总览:Spring技术栈总览
  • 域地图:A00-百科/Java后端/Java后端
最近更新