Spring Bean生命周期
外观
概述[编辑 | 编辑源代码]
Spring Bean生命周期是指从Bean的实例化到销毁的完整过程,由Spring IoC容器管理。理解生命周期对控制Bean行为、资源管理和扩展框架功能至关重要。Spring提供了多种机制(接口、注解、配置)允许开发者介入生命周期的各个阶段。
核心阶段[编辑 | 编辑源代码]
Spring Bean生命周期可分为以下主要阶段(按执行顺序):
1. 实例化[编辑 | 编辑源代码]
容器通过构造器或工厂方法创建Bean实例。此时对象处于"原始状态",依赖未注入。
2. 属性赋值[编辑 | 编辑源代码]
容器通过setter或字段注入完成依赖注入(DI)。若存在循环依赖,Spring会使用三级缓存解决。
3. 初始化[编辑 | 编辑源代码]
- BeanNameAware:设置Bean的ID
- BeanFactoryAware:设置所属BeanFactory
- ApplicationContextAware:设置所属ApplicationContext(需注意与BeanFactory的区别)
- @PostConstruct:注解标记的初始化方法
- InitializingBean:实现
afterPropertiesSet()
方法 - 自定义init-method:XML或
@Bean(initMethod="...")
指定的方法
4. 使用期[编辑 | 编辑源代码]
Bean处于就绪状态,可被应用程序使用。
5. 销毁[编辑 | 编辑源代码]
- @PreDestroy:注解标记的销毁方法
- DisposableBean:实现
destroy()
方法 - 自定义destroy-method:XML或
@Bean(destroyMethod="...")
指定的方法
生命周期流程图[编辑 | 编辑源代码]
代码示例[编辑 | 编辑源代码]
完整生命周期示例[编辑 | 编辑源代码]
public class LifecycleDemo implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean {
private String dependency;
// 1. 构造器
public LifecycleDemo() {
System.out.println("1. 构造器调用");
}
// 2. 属性注入
public void setDependency(String dependency) {
this.dependency = dependency;
System.out.println("2. 依赖注入: " + dependency);
}
// 3. BeanNameAware
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware: " + name);
}
// 4. BeanFactoryAware
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("4. BeanFactoryAware");
}
// 5. ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("5. ApplicationContextAware");
}
// 6. @PostConstruct
@PostConstruct
public void postConstruct() {
System.out.println("6. @PostConstruct");
}
// 7. InitializingBean
@Override
public void afterPropertiesSet() {
System.out.println("7. InitializingBean.afterPropertiesSet()");
}
// 8. 自定义init
public void customInit() {
System.out.println("8. 自定义init-method");
}
// 9. @PreDestroy
@PreDestroy
public void preDestroy() {
System.out.println("9. @PreDestroy");
}
// 10. DisposableBean
@Override
public void destroy() {
System.out.println("10. DisposableBean.destroy()");
}
// 11. 自定义destroy
public void customDestroy() {
System.out.println("11. 自定义destroy-method");
}
}
配置示例[编辑 | 编辑源代码]
<!-- XML配置方式 -->
<bean id="lifecycleDemo" class="com.example.LifecycleDemo"
init-method="customInit" destroy-method="customDestroy">
<property name="dependency" value="示例依赖"/>
</bean>
// Java配置方式
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifecycleDemo lifecycleDemo() {
LifecycleDemo demo = new LifecycleDemo();
demo.setDependency("示例依赖");
return demo;
}
}
实际应用场景[编辑 | 编辑源代码]
数据库连接池管理[编辑 | 编辑源代码]
1. 初始化阶段:创建连接池、预建立连接 2. 使用阶段:提供数据库连接 3. 销毁阶段:关闭所有连接释放资源
缓存预热[编辑 | 编辑源代码]
通过@PostConstruct
在启动时加载热点数据:
@Service
public class CacheService {
private Map<String, Object> cache = new ConcurrentHashMap<>();
@PostConstruct
public void warmUpCache() {
// 从数据库加载热点数据
cache.put("hotProduct", productRepository.findTopSelling());
}
}
高级主题[编辑 | 编辑源代码]
生命周期处理器[编辑 | 编辑源代码]
实现BeanPostProcessor
可拦截所有Bean的初始化过程:
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("处理初始化前: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("处理初始化后: " + beanName);
return bean;
}
}
作用域的影响[编辑 | 编辑源代码]
不同作用域的Bean生命周期表现:
- singleton:容器启动时创建(可配置延迟初始化),容器关闭时销毁
- prototype:每次请求时创建,容器不管理其销毁
- request/session:对应HTTP请求/会话周期
数学表示单例Bean的生命周期:
常见问题[编辑 | 编辑源代码]
Q:初始化方法的执行顺序是什么? A:严格顺序:@PostConstruct → InitializingBean → init-method
Q:如何选择初始化方式? A:推荐优先级:
- @PostConstruct(无框架耦合)
- init-method(XML配置友好)
- InitializingBean(需实现接口)
Q:prototype Bean的@PreDestroy为何不生效?
A:Spring不管理prototype Bean的完整生命周期,需通过@Bean
的destroyMethod或手动调用销毁方法
最佳实践[编辑 | 编辑源代码]
1. 单一职责:每个生命周期方法只做一件事 2. 避免耗时操作:初始化方法应快速完成 3. 防御式编程:检查依赖项是否注入 4. 文档记录:明确记录自定义生命周期方法的作用