深度理解 Spring IoC:从“手动挡”到“自动挡”的演进
在传统的 Java 开发中,如果类 A 依赖于类 B,我们通常会在 A 中通过 new B() 来创建实例。这种方式虽然直观,但会导致类与类之间高度耦合。Spring IoC 的出现彻底改变了这一模式。
- 什么是 IoC(控制反转)?
IoC (Inversion of Control) 并不是一种技术,而是一种设计思想。 !
- 控制**:指对程序执行流程的控制权,以及对依赖对象(Bean)生命周期的管理。**
- 反转**:在传统开发中,程序员掌握控制权;在 Spring 中,控制权被“反转”到了** [Spring IoC 容器]
IoC 与 DI 的关系
- IoC 是目的**:实现对象解耦的思想。**
- DI (Dependency Injection, 依赖注入) 是手段**:Spring 容器在运行期将依赖对象通过构造函数、Setter 方法或注解注入到需要的类中。
- Spring IoC 容器的核心
Spring 提供了两种主要的容器实现来管理 Bean:
- BeanFactory**:最基础的 IoC 容器,提供完整的 IoC 支持。它采用延迟加载(Lazy-loading),只有当请求 Bean 时才进行创建。**
- ApplicationContext**:**
BeanFactory的子接口,也是开发中最常用的容器。它在容器启动时就预先实例化所有单例 Bean,并集成了 AOP、国际化(i18n)等企业级功能。
- IoC 的实现方式
Spring 支持多种方式来定义和配置 Bean:
① 基于 XML 配置文件
最经典的方式,通过 applicationContext.xml 定义 Bean 及其依赖关系。
<bean id="userService" class="com.example.UserService">
<property name="userDao" ref="userDao" />
</bean>
请谨慎使用此类代码。
② 基于注解(Annotation)
现代开发的主流,通过 @Component、@Service、@Autowired 等注解简化配置。
@Service
public class UserService {
@Autowired
private UserDao userDao; // 自动注入依赖
}
请谨慎使用此类代码。
- 引入 IoC 的好处
- 降低耦合度**:对象不再负责搜索或创建其依赖项,代码更易于维护和扩展。**
- 提高可测试性**:在单元测试中,可以轻松地使用 Mock 对象替换真实的依赖项。**
- 生命周期管理**:容器负责 Bean 的初始化、销毁以及单例/多例模式的管理。
- 总结
Spring IoC 就像一个智能工厂。你不再需要自己到处去找零件(new 对象)并组装,而是告诉工厂你需要什么(配置/注解),工厂就会在合适的时候将组装好的成品交给你。这种模式让开发者可以专注于业务逻辑,而非繁琐的对象维护工作。