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.x | XML 配置 | applicationContext.xml |
| Spring 2.5 | 注解驱动 | @Autowired @Component |
| Spring 3.0 | Java 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 容器索引**