1. 为什么我们需要IoC和DI
在传统Java开发中,对象创建和依赖管理通常是这样的:
java复制public class OrderService {
private OrderDao orderDao = new OrderDaoImpl();
public void createOrder() {
orderDao.save();
}
}
这种硬编码方式存在几个明显问题:
- 对象创建逻辑散落在各个业务类中
- 依赖关系难以修改(比如要换OrderDao实现)
- 单元测试困难(无法mock依赖)
Spring的IoC容器通过以下方式解决这些问题:
- 将对象的创建权从程序员手中"反转"给容器
- 通过依赖注入(DI)自动装配对象关系
- 提供统一的配置管理入口
关键理解:IoC是一种设计思想,DI是实现这种思想的具体方式。Spring通过ApplicationContext作为IoC容器实现这一机制。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Spring IoC容器核心实现机制
2.1 容器启动过程解析
Spring IoC容器的初始化流程:
- 资源定位:找到配置文件(XML/注解/JavaConfig)
- 加载解析:将配置转换为BeanDefinition
- 注册存储:将BeanDefinition存入注册表
- 依赖注入:根据依赖关系完成装配
- 初始化回调:执行初始化方法(@PostConstruct等)
java复制// 典型容器初始化代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
OrderService orderService = context.getBean(OrderService.class);
2.2 BeanDefinition详解
每个托管对象在容器中都对应一个BeanDefinition,包含关键元数据:
| 属性 | 说明 | 示例 |
|---|---|---|
| className | Bean的全限定类名 | com.example.OrderServiceImpl |
| scope | 作用域(singleton/prototype等) | singleton |
| lazyInit | 是否延迟初始化 | false |
| initMethodName | 初始化方法 | init |
| propertyValues | 属性值 |
2.3 依赖注入的三种方式
2.3.1 构造器注入
java复制public class OrderService {
private final OrderD
