spring中Bean的生命周期
Spring容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。
而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。
Bean生命周期
Spring Bean的生命周期只有4个阶段:
- 实例化 Instantiation:根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
- 属性赋值 Populate:利用依赖注入完成 Bean 中所有属性值的配置注入。
- 初始化 Initialization:根据Bean的不同定义,完成不同的初始化。比如Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
- 销毁 Destruction
"Spring Bean的生命周期可以分为四个主要阶段:实例化、属性赋值、初始化、销毁。
首先,Spring通过反射实例化Bean。然后进行属性填充,完成依赖注入。接着,Spring会回调一系列Aware接口,让Bean获取容器相关信息。
在初始化阶段,Spring先调用BeanPostProcessor的前置处理方法,然后依次执行@PostConstruct注解方法、InitializingBean接口、以及自定义init-method。初始化完成后,会调用BeanPostProcessor的后置处理方法——这里是AOP创建代理的关键点。
最后,当容器关闭时,会依次执行@PreDestroy、DisposableBean接口和自定义destroy-method来完成销毁。
其中最重要的是BeanPostProcessor,它是Spring扩展性的基石,AOP、注解扫描等核心功能都依赖它来实现。"
代码层面梳理生命周期
@Component public class LifecycleDemoBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private String name; public LifecycleDemoBean() { System.out.println("1. 实例化: 构造函数执行"); } public void setName(String name) { System.out.println("2. 属性赋值: setName方法执行"); this.name = name; } @Override public void setBeanName(String name) { System.out.println("3. BeanNameAware: setBeanName执行"); } @Override public void setBeanFactory(BeanFactory beanFactory) { System.out.println("4. BeanFactoryAware: setBeanFactory执行"); } @Override public void setApplicationContext(ApplicationContext applicationContext) { System.out.println("5. ApplicationContextAware: setApplicationContext执行"); } @PostConstruct public void postConstruct() { System.out.println("6. @PostConstruct: 初始化前置方法执行"); } @Override public void afterPropertiesSet() { System.out.println("7. InitializingBean: afterPropertiesSet执行"); } public void initMethod() { System.out.println("8. init-method: 自定义初始化方法执行"); } @PreDestroy public void preDestroy() { System.out.println("11. @PreDestroy: 销毁前置方法执行"); } @Override public void destroy() { System.out.println("12. DisposableBean: destroy执行"); } public void destroyMethod() { System.out.println("13. destroy-method: 自定义销毁方法执行"); } }
第一阶段:实例化前准备
1. 扫描与解析
Spring启动时,会扫描指定包下的类,将带有@Component等注解的类解析为BeanDefinition,注册到BeanFactory。
2. 合并BeanDefinition
如果Bean有父类,Spring会合并父子Bean的定义信息。
第二阶段:实例化阶段
3. 实例化
Spring通过反射创建Bean的实例。对应输出:"1. 实例化: 构造函数执行",此时Bean还是一个"半成品",属性都还是默认值。
// AbstractAutowireCapableBeanFactory.doCreateBean instanceWrapper = createBeanInstance(beanName, mbd, args);
第三阶段:属性赋值阶段
4. 属性填充
Spring将依赖的其他Bean、配置的值注入到当前Bean中。对应输出:"2. 属性赋值: setName方法执行",这是依赖注入发生的地方,@Autowired、@Value、@Resource在这里处理。
populateBean(beanName, mbd, instanceWrapper);
第四阶段:Aware接口回调
Aware接口是Spring提供的感知型接口,让普通Bean能够获取容器级别的资源和服务。
核心作用有两个:一是让Bean获得对容器的访问能力,比如获取ApplicationContext来发布事件、获取Environment来读取配置;二是解决一些特殊场景的需求,比如通过BeanFactoryAware获取Bean的代理对象来解决事务自调用失效的问题。
Aware的回调发生在Bean生命周期的属性赋值之后、初始化方法之前。Spring通过两个阶段处理Aware:BeanFactoryAware等直接在容器内部调用,而ApplicationContextAware等通过BeanPostProcessor处理。
5. BeanNameAware
如果Bean实现了BeanNameAware,Spring会将Bean的id传入。对应输出:"3. BeanNameAware: setBeanName执行"
6. BeanFactoryAware
如果实现了BeanFactoryAware,Spring会将当前的BeanFactory传入。对应输出:"4. BeanFactoryAware: setBeanFactory执行"
7. ApplicationContextAware
如果实现了ApplicationContextAware,Spring会将当前的ApplicationContext传入。对应输出:"5. ApplicationContextAware: setApplicationContext执行"
第五阶段:BeanPostProcessor前置处理
8. BeanPostProcessor.postProcessBeforeInitialization
在所有初始化方法执行之前,Spring会调用所有BeanPostProcessor的postProcessBeforeInitialization方法。
这是非常重要的扩展点,很多框架在这里做手脚:
-
ApplicationContextAwareProcessor:处理各种Aware接口 -
InitDestroyAnnotationBeanPostProcessor:扫描@PostConstruct等注解
对应输出:这一步没有直接输出,但它会触发第9步
第六阶段:初始化阶段
9. @PostConstruct注解方法
如果Bean中有方法标注了@PostConstruct,在这里执行。对应输出:"6. @PostConstruct: 初始化前置方法执行"
10. InitializingBean.afterPropertiesSet()
如果Bean实现了InitializingBean接口,在这里执行。对应输出:"7. InitializingBean: afterPropertiesSet执行"
11. init-method
如果XML配置或@Bean(initMethod = "xxx")指定了初始化方法,在这里执行。对应输出:"8. init-method: 自定义初始化方法执行"
// AbstractAutowireCapableBeanFactory.invokeInitMethods if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } if (mbd.getInitMethodName() != null) { invokeCustomInitMethod(beanName, bean, mbd); }
第七阶段:BeanPostProcessor后置处理
12. BeanPostProcessor.postProcessAfterInitialization
在初始化方法执行之后,Spring调用所有BeanPostProcessor的postProcessAfterInitialization方法。
这里是AOP代理创建的地方!
-
AbstractAutoProxyCreator在这里检查是否需要为当前Bean创建代理 -
如果需要,这里返回的是代理对象,而不是原始Bean
对应输出:没有直接输出,但这一步完成后,Bean就可以使用了。
// AbstractAutowireCapableBeanFactory.initializeBean Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } invokeInitMethods(beanName, wrappedBean, mbd); if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;
第八阶段:使用阶段
13. Bean就绪
Bean已经准备就绪,驻留在容器中,等待被应用程序使用。
第九阶段:销毁阶段
当容器关闭时,销毁流程开始:
14. @PreDestroy注解方法
如果Bean中有方法标注了@PreDestroy,在这里执行。对应输出:"11. @PreDestroy: 销毁前置方法执行"
15. DisposableBean.destroy()
如果Bean实现了DisposableBean接口,在这里执行。对应输出:"12. DisposableBean: destroy执行"
16. destroy-method
如果指定了自定义销毁方法,在这里执行。对应输出:"13. destroy-method: 自定义销毁方法执行"

浙公网安备 33010602011771号