Skip to content

01.1 — IoC 与 DI 原理

定位: Spring IoC 容器的核心——控制反转与依赖注入的动机与实现 面试高频度: ⭐⭐⭐⭐⭐ 考查方式: 概念理解、三种注入对比、@Autowired 源码级解析

一、这是什么?为什么需要它?

控制反转(IoC):对象的创建权从"应用程序代码"反转到"容器"。没有 IoC 时,对象需要自己 new 依赖的对象,耦合度高、难以测试。

依赖注入(DI):容器在创建对象时,自动将依赖注入到对象中。

二、原理拆解

2.1 三种注入方式对比

方式说明优点缺点
构造器注入通过构造函数参数注入不可变性、必填依赖、易于测试过多参数时臃肿
Setter 注入通过 setXxx() 方法注入可选依赖、可重新赋值可变性、可被覆盖
字段注入 (@Autowired)直接在字段上注解代码简洁无法做 final、难测试、隐藏依赖

Spring 官方推荐:构造器注入(必填依赖),Setter 注入(可选依赖)。

2.2 @Autowired 解析原理

AutowiredAnnotationBeanPostProcessor
    -> 查找字段/方法/构造器
    -> byType 查找候选 Bean
    -> 唯一候选? -> 是: 直接注入
    -> 否: 有 @Primary? -> 是: 注入 @Primary Bean
    -> 否: 有 @Qualifier? -> 是: 按名称精准匹配
    -> 否: 抛出 NoUniqueBeanDefinitionException

核心机制

  • AutowiredAnnotationBeanPostProcessor 负责处理 @Autowired@Inject@Value
  • 首先按**类型(byType)**查找匹配的 Bean
  • 如果找到多个候选,尝试 @Primary 优先
  • 如果仍不唯一,按 @Qualifier 指定名称匹配

2.3 配置方式演进

时期配置方式代表
Spring 2.xXML 配置applicationContext.xml
Spring 2.5注解驱动@Autowired @Component
Spring 3.0Java Config@Configuration @Bean
Spring Boot自动配置约定优于配置
Spring Cloud配置中心集中化外部配置
java
// XML 配置(早期)
<bean id="userService" class="com.example.UserService">
    <property name="userDao" ref="userDao"/>
</bean>

// 注解配置(Spring 2.5+)
@Component
public class UserService {
    @Autowired
    private UserDao userDao;
}

// Java Config(Spring 3.0+,推荐)
@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService(userDao());
    }
    @Bean
    public UserDao userDao() {
        return new UserDao();
    }
}

三、实战验证

java
// 验证 @Autowired 解析行为
@Configuration
public class TestConfig {
    @Bean
    @Primary  // 优先注入
    public UserDao primaryDao() { return new UserDao("primary"); }
    
    @Bean
    public UserDao secondaryDao() { return new UserDao("secondary"); }
}

四、面试视角

追问答案要点
Spring IoC 和 DI 的关系?IoC 是设计思想(控制反转),DI 是具体实现(依赖注入)
构造器注入 vs 字段注入,推荐哪个?构造器注入,因为不可变、易测试、必填依赖明确
@Autowired 如果找到多个候选怎么办?@Primary 优先 -> @Qualifier 按名称 -> 抛异常
@Resource 和 @Autowired 区别?@Resource 按名称(JSR-250),@Autowired 按类型(Spring)

📚 相关链接

  • **Bean生命周期** — Bean 实例化后的完整流程
  • ← 返回 **返回 IoC 容器索引**

Knowledge4J — Java 知识库