本文结合Spring源码5.1.7.RELEASE,详细分析Spring Bean生命周期,包括主要流程以及Spring一系列的扩展方法,最后通过测试实例演示主要步骤。
Spring提供的Bean扩展方法大致分为三类,一类是BeanPostProcessor接口,一类是BeanFactoryProcessor接口,还有一类是Aware接口。
Spring Bean的生命周期概括下来,主要分4个大阶段:实例化-->属性赋值-->初始化-->销毁。主要流程图如下:
以下部分,按步骤分别解析各个阶段。
一、BeanDefination解析及合并
首先说明一个概念,BeanDefination是什么?BeanDefination就是Bean的元信息,用来描述Bean的各种信息,包括Bean作用域、是否是Primary、字段值、初始化方法等,Bean的元信息的抽象。在Spring创建Bean之前,会有Bean的元信息解析及合并。
元信息的解析发生在AbstractApplicationContext#refresh-->obtainFreshBeanFactory()-->AbstractRefreshableApplicationContext#refreshBeanFactory()-->loadBeanDefinitions()方法。loadBeanDefinitions是一个抽象方法,Spring有不同类型的实现,包括xml解析、注解解析等。
元信息之所以需要做合并,就是因为Java的继承,子类的Bean在进行装配之前,必须把其父类的元信息合并到当前子类当中。元信息的合并发生在AbstractBeanFactory#doGetBean方法中。
getMergedLocalBeanDefinition()方法跟踪到最后一步,分析getMergedBeanDefinition方法源码分析如下:
二、实例化
2.1 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
元信息准备好之后,进入Bean实例化阶段,来到流程图中的第一个扩展接口InstantiationAwareBeanPostProcessor。
首先看看AbstractAutowireCapableBeanFactory#createBean的代码:
跟踪调用点方法resolveBeforeInstantiation,代码如下:
结合两个方法的代码逻辑可知,在开始实例化之前,如果resolveBeforeInstantiation返回有Bean的实例,后续doCeateBean方法里全部逻辑,即属性赋值、初始化等,都不会再执行。
InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法默认实现是返回null,所以可以自行实现该接口,在创建Bean的时候返回特定的Bean实例,用作代理,替换原来的Bean,这里也是Spring AOP编程的体现。 2.2 实例化createBeanInstanceBean的实例化、属性赋值和初始化三个阶段的代码都在AbstractAutowireCapableBeanFactory#doCreateBean方法中,代码如下:
createBeanInstance方法简单来说,就是通过构造器方法实例化对象的过程,代码解析如下:
2.3 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
postProcessAfterInstantiation方法的调用点在属性赋值方法populateBean当中,代码解析如下:
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation接口的作用是判断是否需要为Bean进行后续的属性赋值。用户可实现该接口,为指明的Bean跳过属性赋值阶段,但后续的初始化依然会执行。
三、属性赋值
3.1 InstantiationAwareBeanPostProcessor#postProcessProperties
通过populateBean的代码解析可知,postProcessProperties和postProcessPropertyValues都是为了获取PropertyValues。PropertyValues封装的是以K-V形式存储的Bean的属性和值。实现postProcessProperties方法,就可对特定的Bean对象的初始属性值进行自定义设置和修改。
3.2 属性填充applyPropertyValues
属性填充的过程很简单,就是直接把PropertyValues填充到BeanWrapper中。BeanWrapper是对Bean的包装,将对Bean属性访问和类型转换相关的操作封装到BeanWrapper。
四、初始化
初始化的代码解析如下:
4.1 Aware接口回调--第一部分
Aware是Spring开放出来的,用于对Bean起标识作用的超级接口。Spring一系列Aware接口的执行顺序如流程图所示,分两部分。
第一部分的BeanNameAware、BeanClassLoaderAware和BeanFactoryAware在initializeBean方法中的invokeAwareMethod方法中调用。代码解析如下:
声明的Bean可以实现Spring全部的Aware接口,重写相应的set方法,即可对当前的Bean进行相应的增强和描述。
4.2 BeanPostProcessor#postProcessBeforeInitialization
Aware接口的第二部分部分调用在applyBeanPostProcessorsBeforeInitialization方法中。applyBeanPostProcessorsBeforeInitialization实际调用BeanPostProcessor#postProcessBeforeInitialization。在BeanPostProcessor的实现类ApplicationContextAwareProcessor重写了postProcessBeforeInitialization方法。
ApplicationContextAwareProcessor#postProcessBeforeInitialization中,有第二部分Aware接口:EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware和ApplicationContextAware的调用链。
值得另外说明的是, BeanPostProcessor还有一个实现类InitDestroyAnnotationBeanPostProcessor,同样重写了postProcessBeforeInitialization方法。这里在调用BeanPostProcessor#postProcessBeforeInitialization方法时,InitDestroyAnnotationBeanPostProcessor也会被触发。InitDestroyAnnotationBeanPostProcessor类用于调用Bean中声明了@PostConstruct和@PreDestroy注解的初始化方法和销毁方法。
4.3 InitializingBean#afterPropertiesSet
afterPropertiesSet方法是Bean初始化方式的一种,Bean自己可以实现InitializingBean接口,在invokeInitMethods方法达到调用点时触发afterPropertiesSet,进行Bean初始化操作。代码解析如下:
4.4 自定义初始化方法
声明Bean的时候,还可以指定自定义初始化方法,也就是@Bean注解中initMethod属性。invokeCustomInitMethod会通过反射调用initMethod指明的,Bean中自定义的方法。
如果Bean同时声明了上面三种初始化方法,那么这里的执行顺序就是:@PostConstruct--->InitializingBean#afterPropertiesSet--->initMethod。
4.5 BeanPostProcessor#postProcessAfterInitialization
在初始化方法全部执行结束之后,紧接着就会开始调用postProcessAfterInitialization方法。代码解析如下:
从代码中可以看到,如果postProcessAfterInitialization返回的对象不为空,会用返回的对象替换前面初始化好的对象。
整个流程执行到这里,代表Bean已经创建好了。后续根据作用域的不同,情况亦不同,单例的Bean由Spring负责销毁,其他由用户自己控制生命周期的终结。
五、销毁
Bean的销毁阶段的代码逻辑在DisposableBeanAdapter#destroy方法中,代码解析如下:
这里的第一步需要注意,DestructionAwareBeanPostProcessor是一个接口,也就是说,用户可以自定义接口实现,重写postProcessBeforeDestruction方法实现自己的逻辑。然后Spring本身有一个类CommonAnnotationBeanPostProcessor,实现了DestructionAwareBeanPostProcessor接口,用于处理@Predestory和@PostConstruct注解逻辑,这里也会执行。
从上面代码解析可以看到,Sping Bean的销毁阶段跟初始化阶段类似,也存在三种销毁方法,其执行步骤是:@Predestory--->DisposableBean#destory--->自定义destory方法。
六、代码演示
根据上述二到五部分的源码解析,编写演示代码。
6.1 自定义InstantiationAwareBeanPostProcessor
@Component public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if ("user".equals(beanName)) { System.out.println("1. 调用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() 方法"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("user".equals(beanName)) { System.out.println("3. 调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() 方法"); } return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if ("user".equals(beanName)) { System.out.println("4. 调用 InstantiationAwareBeanPostProcessor.postProcessProperties() 方法"); } return null; } }
6.2 自定义BeanPostProcessor
@Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("user".equals(beanName)) { System.out.println("10. 调用 BeanPostProcessor.postProcessBeforeInitialization() 方法"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("user".equals(beanName)) { System.out.println("14. 调用 BeanPostProcessor.postProcessAfterInitialization() 方法"); } return bean; } }
6.3 Bean定义
@Data public class User implements InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware { private int id; private String name; public User(int id, String name) { this.id = id; this.name = name; System.out.println("2. 调用构造函数"); } @Override public void setBeanName(String name) { System.out.println("5. 调用 BeanNameAware.setBeanName() 方法"); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("6. 调用 BeanClassLoaderAware.setBeanClassLoader() 方法"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("7. 调用 BeanFactoryAware.setBeanFactory() 方法"); } @Override public void setEnvironment(Environment environment) { System.out.println("8. 调用 EnvironmentAware.setEnvironment() 方法"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("9. 调用 ApplicationContextAware.setApplicationContext() 方法"); } @PostConstruct public void postInit() { System.out.println("11. 调用 PostConstruct 初始化 方法"); } @Override public void afterPropertiesSet() { System.out.println("12. 调用 InitializingBean.afterPropertiesSet() 方法"); } public void myInit() { System.out.println("13. 调用 init-method 方法"); } @PreDestroy public void myDestroy() { System.out.println("15. 调用 PreDestroy 方法"); } @Override public void destroy() { System.out.println("16. 调用 DisposableBean.destroy() 方法"); } public void myDestroyMethod() { System.out.println("17. 调用 destroy-method 方法"); } }
测试代码运行效果如下:
测试效果符合流程图所示。
到此,Spring Bean生命周期全阶段解析完成。
标签:调用,Spring,Bean,详解,println,方法,public,out From: https://www.cnblogs.com/sunshine-ground-poems/p/17306258.html