Spring bean生命周期
前言
在Spring 框架中,代码定义的对象统一由Spring 容器管理,由Spring容器来创建,初始化。
那么一个bean的简版生命周期如下图:
图一
实例化一个bean对象,完成属性注入,执行初始化方法,此时bean可以被我们所使用,最后销毁。
Spring也赋予了一个bean在上述4个阶段中做一些增强的操作,下文详细分析。
Spring bean生命周期
Spring bean详细生命周期流程图:
图二
从doCreateBean() 方法开始
AbstractAutowireCapableBeanFactory抽象类:
省略部分代码
protected?Object?doCreateBean(String?beanName,?RootBeanDefinition?mbd,?@Nullable?Object[]?args)
???throws?BeanCreationException?{
??//?Instantiate?the?bean.
??BeanWrapper?instanceWrapper?=?null;
??if?(mbd.isSingleton())?{
???instanceWrapper?=?this.factoryBeanInstanceCache.remove(beanName);
??}
??if?(instanceWrapper?==?null)?{
??????//实例化
???instanceWrapper?=?createBeanInstance(beanName,?mbd,?args);
??}
??Object?bean?=?instanceWrapper.getWrappedInstance();
??//?Initialize?the?bean?instance.
??Object?exposedObject?=?bean;
????//属性填充
????populateBean(beanName,?mbd,?instanceWrapper);
????//初始化bean实例
????exposedObject?=?initializeBean(beanName,?exposedObject,?mbd);
??return?exposedObject;
?}
在doCreateBean()方法中:
initializeBean()方法
AbstractAutowireCapableBeanFactory抽象类:
protected?Object?initializeBean(String?beanName,?Object?bean,?@Nullable?RootBeanDefinition?mbd)?{
??if?(System.getSecurityManager()?!=?null)?{
???AccessController.doPrivileged((PrivilegedAction<Object>)?()?->?{
????invokeAwareMethods(beanName,?bean);
????return?null;
???},?getAccessControlContext());
??}
??else?{
??????//调用感知方法
???invokeAwareMethods(beanName,?bean);
??}
??Object?wrappedBean?=?bean;
??if?(mbd?==?null?||?!mbd.isSynthetic())?{
??????//初始化前调用bean后置处理器
???wrappedBean?=?applyBeanPostProcessorsBeforeInitialization(wrappedBean,?beanName);
??}
??try?{
??????//调用初始化方法
???invokeInitMethods(beanName,?wrappedBean,?mbd);
??}
??catch?(Throwable?ex)?{
???throw?new?BeanCreationException(
?????(mbd?!=?null???mbd.getResourceDescription()?:?null),
?????beanName,?"Invocation?of?init?method?failed",?ex);
??}
??if?(mbd?==?null?||?!mbd.isSynthetic())?{
??????//初始化后调用bean后置处理器
???wrappedBean?=?applyBeanPostProcessorsAfterInitialization(wrappedBean,?beanName);
??}
??return?wrappedBean;
?}
在initializeBean()方法中:
invokeAwareMethods() 方法注入相关属性
private?void?invokeAwareMethods(String?beanName,?Object?bean)?{
??if?(bean?instanceof?Aware)?{
???if?(bean?instanceof?BeanNameAware)?{
????((BeanNameAware)?bean).setBeanName(beanName);
???}
???if?(bean?instanceof?BeanClassLoaderAware)?{
????ClassLoader?bcl?=?getBeanClassLoader();
????if?(bcl?!=?null)?{
?????((BeanClassLoaderAware)?bean).setBeanClassLoader(bcl);
????}
???}
???if?(bean?instanceof?BeanFactoryAware)?{
????((BeanFactoryAware)?bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
???}
??}
?}
applyBeanPostProcessorsBeforeInitialization() 和
applyBeanPostProcessorsAfterInitialization() 方法中会获取bean后置处理器集合,依次执行:
自定义init方法
图二中调用自定义init方法invokeCustomInitMethod() 是指:
验证
@Component
@Slf4j
@Scope(value?=?"prototype")
@PropertySource({"classpath:bootstrap.yml"})
public?class?FullBean?implements?BeanNameAware,?BeanFactoryAware,?ApplicationContextAware,?InitializingBean,
????????InstantiationAwareBeanPostProcessor,
????????BeanPostProcessor,
????????DisposableBean?{
????private?String?name;
????public?FullBean()?{
????????log.info("无参构造方法:?{}",?this);
????}
????@Value("${name}")
????public?void?setName(String?name)?{
????????log.info("setName:?{}",?name);
????????this.name?=?name;
????}
????@Override
????public?void?setBeanName(String?name)?{
????????log.info("beanName:?{}",?name);
????}
????
????@Override
????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
????????log.info("beanFactory:?{}",?beanFactory.getClass());
????}
????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????log.info("applicationContext:?{}",?applicationContext.getId());
????}
????@PostConstruct
????public?void?postConstruct()?{
????????log.info("postConstruct执行");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????log.info("afterPropertiesSet执行");
????}
????@Override
????public?Object?postProcessBeforeInstantiation(Class<?>?beanClass,?String?beanName)?throws?BeansException?{
????????log.info("实例化前:?{}",?beanName);
????????return?null;
????}
????@Override
????public?boolean?postProcessAfterInstantiation(Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("实例化后:?{}",?beanName);
????????return?true;
????}
????@Override
????public?PropertyValues?postProcessProperties(PropertyValues?pvs,?Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("后处理属性注入:?{}",?beanName);
????????return?null;
????}
????@Override
????public?PropertyValues?postProcessPropertyValues(PropertyValues?pvs,?PropertyDescriptor[]?pds,?Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("属性注入:?{}",?beanName);
????????return?pvs;
????}
????@Override
????public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("初始化前:?{}",?beanName);
????????return?bean;
????}
????@Override
????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????log.info("初始化后:?{}",?beanName);
????????return?bean;
????}
????@Override
????public?void?destroy()?throws?Exception?{
????????log.info("bean销毁");
????}
}
执行结果:
实现BeanPostProcessor接口不生效原因
单例模式下:
bean作用域默认为单例,也可以在bean上加 @Scope(value = "singleton")。 此时FullBean类中不会执行BeanPostProcessor接口覆盖的方法。
原因:
在AbstractApplicationContext#refresh() -> registerBeanPostProcessors() 方法中,FullBean由于实现了BeanPostProcessor接口,会被提前初始化,此时FullBean还未注册到BeanPostProcessor集合中。
refresh()方法分析见:Spring boot启动流程分析精简版
registerBeanPostProcessors() 方法会调用 PostProcessorRegistrationDelegate#registerBeanPostProcessors()
由于fullBean 是一个后置处理器类,那么此时fullBean 会先被创建,并放入单例缓存池中(缓存在DefaultSingletonBeanRegistry 类的singletonObjects 属性 map集合中),接着会将此bean注册到BeanPostProcessor 集合中。所以在单例情况下,实现了BeanPostProcessor 接口后,不会执行其实现的方法。
后面 getBean("fullBean") 直接从缓存中获取bean 实例。
原型模式下:
在类上注解@Scope(value = "prototype") 设置此bean作用域为原型模式。容器启动时由于fullBean 是后置处理器类,也不会执行。
Spring 应用容器启动完毕后,下一次getBean("fullBean") 时,会再次创建bean对象,此时会执行其后置处理器覆盖的方法。
小结
本文分析了核心的关键流程,旨在了解bean 的生命周期。建议对照图二的流程图,去debug 源码会更加清晰。
注:类初始化和bean生命周期中的初始化不是一个概念
|