IoC容器中的Bean生命周期管理
字数 1543 2025-11-08 20:56:49
IoC容器中的Bean生命周期管理
描述
Bean生命周期管理是IoC容器的核心机制,指容器如何创建、初始化、依赖注入、使用和销毁Bean对象的完整过程。掌握生命周期能深入理解框架行为,解决配置失效、资源泄漏等实际问题。典型场景包括:数据库连接池的初始化和关闭、缓存数据的预加载、定时任务的自动启停。
生命周期阶段详解
-
实例化(Instantiation)
- 容器通过反射或工厂模式创建Bean的原始对象(如
new UserService())。 - 若配置了工厂方法(如
@Bean),则调用指定方法生成对象。 - 此时对象处于"原始状态",依赖未注入,类似裸机刚组装完成。
- 容器通过反射或工厂模式创建Bean的原始对象(如
-
依赖注入(Dependency Injection)
- 容器扫描Bean的字段或setter方法,按类型/名称查找依赖对象并注入。
- 循环依赖问题在此阶段暴露,容器通过三级缓存等机制解决(例如Spring使用早期引用暴露)。
- 示例:
UserService中标记@Autowired的UserDao字段被自动赋值。
-
初始化前回调(Post-Process Before Initialization)
- 若Bean实现了
InitializingBean接口,调用afterPropertiesSet()方法。 - 执行自定义
@PostConstruct注解的方法(如验证配置合法性)。 - 容器在此阶段可修改Bean(如代理包装),通过
BeanPostProcessor接口实现。
- 若Bean实现了
-
初始化(Initialization)
- 若配置了
init-method(XML)或@Bean(initMethod="init"),执行指定方法。 - 常见用途:建立网络连接、加载静态数据。需注意异常处理——初始化失败会阻止Bean投入使用。
- 若配置了
-
初始化后回调(Post-Process After Initialization)
- 执行
BeanPostProcessor的postProcessAfterInitialization()方法。 - AOP代理在此阶段生成:原始Bean被包装成代理对象,后续调用会切入增强逻辑。
- 此时Bean已准备就绪,可被其他对象使用。
- 执行
-
就绪与使用(Ready & Usage)
- Bean驻留在容器的单例池(Singleton Registry)中,响应业务请求。
- 容器根据作用域(Scope)管理状态:单例Bean全局共享,原型(Prototype)每次请求创建新实例。
-
销毁前回调(Pre-Destroy)
- 容器关闭时,先调用
@PreDestroy注解的方法(如清理线程池)。 - 实现
DisposableBean接口的Bean会触发destroy()方法。
- 容器关闭时,先调用
-
销毁(Destruction)
- 执行自定义
destroy-method(如close()释放数据库连接)。 - 容器解除引用,Bean进入GC可回收状态。
- 执行自定义
实践示例(Spring框架)
@Component
public class DatabasePool implements InitializingBean, DisposableBean {
@Autowired private DataSourceConfig config;
private List<Connection> connections;
@PostConstruct
public void validateConfig() {
if (config.getMaxSize() <= 0) throw new IllegalStateException();
}
@Override
public void afterPropertiesSet() {
this.connections = IntStream.range(0, config.getMinSize())
.mapToObj(i -> createConnection())
.collect(Collectors.toList());
}
@PreDestroy
public void clear() {
connections.forEach(Connection::close);
}
@Override
public void destroy() {
System.out.println("Connection pool shutdown");
}
}
关键设计模式
- 模板方法模式:生命周期阶段由容器固定流程控制,用户通过钩子方法(如
@PostConstruct)介入。 - 观察者模式:容器事件(如
ContextRefreshedEvent)通知监听器执行特定逻辑。 - 装饰器模式:
BeanPostProcessor对Bean进行功能增强(如日志包装)。
常见问题与解决方案
- 循环依赖:使用setter注入而非构造器注入,或调整Bean依赖关系。
- 资源泄漏:确保
@PreDestroy方法被调用(Web应用需注册ServletContextListener主动关闭容器)。 - 作用域误区:原型Bean的生命周期不包含销毁阶段,需手动管理资源。