这篇本来要介绍这个finishBeanFactoryInitialization(beanFactory)实例化方法的,但考虑到这里面涉及的东西实在很多,决定进行拆分介绍,先介绍spring bean的生命周期、生命周期在源码的体现以及怎么完成自动注入的、然后在介绍spring怎么解决循环依赖的。这篇先来介绍下spring bean的生命周期。
生命周期概览
spring生命周期从总体上说,分为实例化之前,实例化,实例化之后,自动注入,AWare,初始化之前,初始化,初始化之后这些流程,具体各流程代码方法调用顺序体现为以下:
实例化之前
1、InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法、
实例化
2、构造方法
实例化之后
3、MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法
4、InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法
5、InstantiationAwareBeanPostProcessor#postProcessProperties方法
自动注入
6、自动注入
AWare
7、各种Aware的调用,
初始化之前
8、PostConstruct注解(注意这个我放到初始化之前阶段)
9、BeanPostProcessor#postProcessBeforeInitialization方法
初始化
10、InitializingBean#afterPropertiesSet方法
初始化之后
11、BeanPostProcessor#postProcessAfterInitialization方法
销毁
12、销毁方法。
生命周期详解
spring生命周期包括以下流程,实例化之前,实例化,实例化之后,自动注入,AWare,初始化之前,初始化,初始化之后,销毁,牢记这些流程,下面就是已这个流程顺序进行分析。spring提供相应的钩子,供用户自定义这些流程。InstantiationAwareBeanPostProcessor是实例化之前,实例化之后的钩子,一共有3个方法,postProcessBeforeInstantiation,postProcessAfterInstantiation,postProcessProperties。postProcessBeforeInstantiation方法作用于实例化之前,如果返回不为null,这个bean对象的生命周期会直接跳到初始化之后这一个流程,aop正是通过postProcessBeforeInstantiation方法返回一个代理对象,进而实现代理,postProcessAfterInstantiation方法是在实例化之后调用的,返回值为一个布尔值,如果返回为true,则会调用postProcessProperties方法,进行bean属性的后置处理。如果返回为false,则不会调用postProcessProperties,也不会进行属性注入。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
*在实例化对象之前调用,这里可以返回一个代理对象,当返回不为null,会直接调用
*BeanPostProcessor的postProcessAfterInitialization方法
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
*在实例化之后调用,属性注入之前调用。如果返回为false,则不进行属性注入过程,返回为true的调
*用下面postProcessProperties方法。
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
*后置处理bean的属性值,
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
*已废弃
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
在实例化之后这一流程,还有一个钩子,就是MergedBeanDefinitionPostProcessor,它的调用时机为InstantiationAwareBeanPostProcessor #postProcessAfterInstantiation方法之前,实例化之后。要理解MergedBeanDefinitionPostProcessor,先得理解MergedBeanDefinition,当然spring没这个官方概念的,它翻译为已合并的BeanDefinition。这里可能感到奇怪,啥叫已合并,其实在spring创建bean的过程中,可能不只需要一个beanDefinition,而需要多个beanDefinition。比如在student类继承person类型,在创建student类的bean时,需要student和person的beanDefinition,也就是说,spring是以MergedBeanDefinition为原料,创建bean的。MergedBeanDefinitionPostProcessor就是用对MergedBeanDefinition初始化或者一些元数据,这些元数据可以供InstantiationAwareBeanPostProcessor #postProcessProperties方法使用,进行属性赋值,spring 自动注入也是利用这原理进行实现的,具体实现为AutowiredAnnotationBeanPostProcessor,它实现了InstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor,AutowiredAnnotationBeanPostProcessor先通过MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,获取到InjectionMetadata对象,这个对象保存了bean需要注入的元数据,有了这个InjectionMetadata对象,再通过InstantiationAwareBeanPostProcessor #postProcessProperties方法完成属性的自动注入。
通过上面,我们已经明白了实例化之前,实例化,实例化之后,自动注入这四个流程中,spring提供的生命周期钩子,主要是两个接口,InstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor。而自动注入也是通过实现这两个钩子,进而完成注入流程。
Aware的中文意思为感知,当某个bean实现了xxxAware接口时,就表示bean就能获得xxx,spring 提供Aware有BeanNameAware 、BeanClassLoaderAware 、 BeanFactoryAware 、ResourceLoaderAware 、 ApplicationContextAware 、MessageSourceAware 、ApplicationEventPublisherAware等等,下面这个Student类实现了ApplicationContextAware接口,就代表Student类能感知到ApplicationContext,在以后的方法就可以使用ApplicationContext这个对象。
@Component
public class Student implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
public void test(){
//因为实现了ApplicationContextAware 接口,所以就能在test方法中使用applicationContext对象。
System.out.println(applicationContext);
}
}
初始化主要的方式为实现InitializingBean接口。至于初始化之前和初始化之后的生命周期钩子,就是BeanPostProcessor接口了,它有个两个方法,postProcessBeforeInitialization,postProcessAfterInitialization,为初始化前,初始化后的回调方法。销毁方法就是DisposableBean的提供方法了。
好了,上面就是我对spring bean生命周期的理解,下篇详解生命周期在源码体现,以及怎么实现自动注入的。