深入理解 Spring Bean 生命周期:从实例化到销毁

在 Spring 框架中,Bean 的生命周期是理解容器管理机制的核心。本文将通过图示和代码示例,详细解析 Spring Bean 从创建到销毁的完整流程,并解答常见疑问:是否可以在初始化前跳过属性赋值?

Bean 生命周期概览

Spring Bean 的生命周期大致分为以下几个阶段:

  1. 实例化:通过构造方法创建 Bean 对象。
  2. 属性赋值:为 Bean 的依赖和属性注入值。
  3. BeanNameAware:设置 Bean 名称。
  4. BeanFactoryAware:设置 BeanFactory。
  5. ApplicationContextAware:设置 ApplicationContext。
  6. 初始化前处理:BeanPostProcessor.postProcessBeforeInitialization。
  7. @PostConstruct 注解方法:初始化逻辑执行。
  8. InitializingBean.afterPropertiesSet:属性设置完成后的回调。
  9. 自定义 init 方法:通过 @Bean(initMethod) 指定。
  10. 初始化后处理:BeanPostProcessor.postProcessAfterInitialization。
  11. Bean 使用阶段:Bean 已准备就绪,可用于业务逻辑。
  12. @PreDestroy 注解方法:销毁前回调。
  13. DisposableBean.destroy:销毁方法执行。
  14. 自定义 destroy 方法:通过 @Bean(destroyMethod) 指定。

代码示例

1. 主配置类

less

@Configuration @ComponentScan("com.example.lifecycle") public class AppConfig { @Bean(initMethod = "customInit", destroyMethod = "customDestroy") public ExampleBean exampleBean() { return new ExampleBean(); } }

2. Bean 生命周期类

csharp

public class ExampleBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private String name; public ExampleBean() { System.out.println("1. Bean 实例化 - 构造函数执行"); } public void setName(String name) { this.name = name; System.out.println("2. 属性赋值 - 设置属性值: " + name); } @Override public void setBeanName(String name) { System.out.println("3. BeanNameAware - Bean 名称: " + name); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("4. BeanFactoryAware - 设置 BeanFactory"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("5. ApplicationContextAware - 设置 ApplicationContext"); } @PostConstruct public void postConstruct() { System.out.println("7. @PostConstruct - 初始化方法"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("8. InitializingBean.afterPropertiesSet - 属性设置完成后"); } public void customInit() { System.out.println("9. 自定义 init 方法 - @Bean(initMethod)"); } public void doSomething() { System.out.println("11. Bean 使用中 - 业务方法执行"); } @PreDestroy public void preDestroy() { System.out.println("12. @PreDestroy - 销毁前方法"); } @Override public void destroy() throws Exception { System.out.println("13. DisposableBean.destroy - 销毁方法"); } public void customDestroy() { System.out.println("14. 自定义 destroy 方法 - @Bean(destroyMethod)"); } }

3. BeanPostProcessor 实现

typescript

@Component public class CustomBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof ExampleBean) { System.out.println("6. BeanPostProcessor.postProcessBeforeInitialization - 初始化前处理"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof ExampleBean) { System.out.println("10. BeanPostProcessor.postProcessAfterInitialization - 初始化后处理"); } return bean; } }

4. 测试类

arduino

import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class LifecycleTest { public static void main(String[] args) { System.out.println("=== Spring Bean 生命周期演示 ==="); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); ExampleBean exampleBean = context.getBean(ExampleBean.class); exampleBean.doSomething(); System.out.println("=== 关闭 Spring 容器 ==="); context.close(); } }


输出结果

markdown

=== Spring Bean 生命周期演示 === 1. Bean 实例化 - 构造函数执行 2. 属性赋值 - 设置属性值: null 3. BeanNameAware - Bean 名称: exampleBean 4. BeanFactoryAware - 设置 BeanFactory 5. ApplicationContextAware - 设置 ApplicationContext 6. BeanPostProcessor.postProcessBeforeInitialization - 初始化前处理 7. @PostConstruct - 初始化方法 8. InitializingBean.afterPropertiesSet - 属性设置完成后 9. 自定义 init 方法 - @Bean(initMethod) 10. BeanPostProcessor.postProcessAfterInitialization - 初始化后处理 11. Bean 使用中 - 业务方法执行 === 关闭 Spring 容器 === 12. @PreDestroy - 销毁前方法 13. DisposableBean.destroy - 销毁方法 14. 自定义 destroy 方法 - @Bean(destroyMethod)

初始化前是否可以跳过属性赋值?

答案是否定的。Spring 的设计理念是:

属性赋值必须在初始化阶段之前完成

原因如下:

  1. 初始化逻辑通常依赖 Bean 已经注入的属性。
  2. 如果初始化方法提前执行,未注入属性可能导致 NullPointerException 或状态不完整。
  3. Bean 的生命周期有严格顺序,确保每个阶段都能安全执行。

因此,即便在 @PostConstruct、InitializingBean.afterPropertiesSet 或自定义初始化方法中访问 Bean 属性,也可以放心使用,不会出现未赋值的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值