从BeanFactory源码看Bean的生命周期
作者:互联网
Bean生命周期简单描述#
我们先不看那些繁杂的生命周期方法回调,只看核心的部分,也就是图中四个大的黄色块
根据BeanDefinition创建Bean,这个过程称为实例化
填充Bean的属性
这时,Bean已经创建完毕并可以投入使用,这时需要调用Bean的初始化方法(如果用户指定了的话),这个过程称为初始化
Bean被销毁
所以,可以将Bean的创建归纳为:
实例化
设置属性
初始化
销毁
虽然上面我们把大部分的繁杂的生命周期Hook给屏蔽了,总结出了四个核心的过程,但是这些Hook给了Spring框架带来了无尽的灵活性,所以也是非常重要的。但它们太容易让人眼花了,所以在继续之前,我们有必要先介绍一下那些东西都是什么,是用来解决什么问题的。
BeanPostProcessor接口#
BeanPostProcessor接口有如下方法:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
从方法名上看,xxxxBeforeInitialization,xxxAfterInitialization,意思是在初始化阶段前后做一些事,它的参数中,有实际创建出来的Bean和Bean的名字,该方法默认情况下返回原始的bean,也可以返回该bean的某种代理,实际上AOP就是通过这个接口来实现bean代理的返回的。
所以,BeanPostProcessor实际关心的是Bean的初始化阶段。
ConfigurableBeanFactory接口的addBeanPostProcessor方法可以向BeanFactory中注册BeanPostProcessor
InstantiationAwareBeanPostProcessor#
首先,它继承BeanPostProcessor,所以它是一个BeanPostProcessor。但是从名字来看,InstantiationAware表示它更关心对于Bean的实例化阶段的感知,而不是初始化阶段,它发生在初始化阶段前面。
它的方法如下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
// 省略一个过时方法...
}
首先,xxxBeforeInstantiation、xxxAfterInstantiation是很容易和之前的两个搞混的,不过以Instantiation结尾代表着它们关心的是Bean实例化的前后,在实例化前,该方法同样允许返回一个代替该Bean的对象,不过这次由于Bean还没有实际创建出来,所以它的参数中没有Bean对象,而是该Bean的Class对象。而在实例化后,它允许返回一个布尔值来指定是否该对该Bean的属性进行设置(true设置,false跳过)。
Aware生命周期感知接口#
Aware接口里啥也没有,有方法的是它的子接口
public interface Aware { }
Aware被一个想要感知到框架中的某种信息的Bean实现,比如一个Bean可能对创建它的Bean工厂感兴趣,那么它可以实现这个接口:
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
Bean工厂会在该Bean的初始化阶段检测该Bean是否实现了这个接口,如果实现了就调用它的setBeanFactory方法将工厂设置进去。
请注意,Aware被Bean实现,作用于单个Bean,BeanPostProcessor被注册到Bean工厂中,作用于工厂中的每个Bean。
实例化Bean&属性设置#
这图里所描述的是,创建Bean时先从BeanDefinition开始,然后实例化Bean,在实例化前后,InstantiationAwareBeanPostProcessor会被调用。
下面从doGetBean方法开始(getBean方法实际调用的方法,它已经是AbstractBeanFactory中的方法了),看下面的代码需要注意,Spring中Bean的作用域可以分为Singleton、Prototype和其它,其中Singleton和Prototype是Spring框架原生支持的,其它作用域需要自行扩展,比如SpringWebMVC扩展了Session等作用域。所以你看下面的代码时也要在脑袋里把它们分成Singleton、Prototype和其它作用域,要不然你可能就被这很长很长的代码搞迷糊了
我们先不看那些繁杂的生命周期方法回调,只看核心的部分,也就是图中四个大的黄色块
根据BeanDefinition创建Bean,这个过程称为实例化
填充Bean的属性
这时,Bean已经创建完毕并可以投入使用,这时需要调用Bean的初始化方法(如果用户指定了的话),这个过程称为初始化
Bean被销毁
所以,可以将Bean的创建归纳为:
实例化
设置属性
初始化
销毁
虽然上面我们把大部分的繁杂的生命周期Hook给屏蔽了,总结出了四个核心的过程,但是这些Hook给了Spring框架带来了无尽的灵活性,所以也是非常重要的。但它们太容易让人眼花了,所以在继续之前,我们有必要先介绍一下那些东西都是什么,是用来解决什么问题的。
BeanPostProcessor接口#
BeanPostProcessor接口有如下方法:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
从方法名上看,xxxxBeforeInitialization,xxxAfterInitialization,意思是在初始化阶段前后做一些事,它的参数中,有实际创建出来的Bean和Bean的名字,该方法默认情况下返回原始的bean,也可以返回该bean的某种代理,实际上AOP就是通过这个接口来实现bean代理的返回的。
所以,BeanPostProcessor实际关心的是Bean的初始化阶段。
ConfigurableBeanFactory接口的addBeanPostProcessor方法可以向BeanFactory中注册BeanPostProcessor
InstantiationAwareBeanPostProcessor#
首先,它继承BeanPostProcessor,所以它是一个BeanPostProcessor。但是从名字来看,InstantiationAware表示它更关心对于Bean的实例化阶段的感知,而不是初始化阶段,它发生在初始化阶段前面。
它的方法如下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
// 省略一个过时方法...
}
首先,xxxBeforeInstantiation、xxxAfterInstantiation是很容易和之前的两个搞混的,不过以Instantiation结尾代表着它们关心的是Bean实例化的前后,在实例化前,该方法同样允许返回一个代替该Bean的对象,不过这次由于Bean还没有实际创建出来,所以它的参数中没有Bean对象,而是该Bean的Class对象。而在实例化后,它允许返回一个布尔值来指定是否该对该Bean的属性进行设置(true设置,false跳过)。
Aware生命周期感知接口#
Aware接口里啥也没有,有方法的是它的子接口
public interface Aware { }
Aware被一个想要感知到框架中的某种信息的Bean实现,比如一个Bean可能对创建它的Bean工厂感兴趣,那么它可以实现这个接口:
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
Bean工厂会在该Bean的初始化阶段检测该Bean是否实现了这个接口,如果实现了就调用它的setBeanFactory方法将工厂设置进去。
请注意,Aware被Bean实现,作用于单个Bean,BeanPostProcessor被注册到Bean工厂中,作用于工厂中的每个Bean。
实例化Bean&属性设置#
这图里所描述的是,创建Bean时先从BeanDefinition开始,然后实例化Bean,在实例化前后,InstantiationAwareBeanPostProcessor会被调用。
下面从doGetBean方法开始(getBean方法实际调用的方法,它已经是AbstractBeanFactory中的方法了),看下面的代码需要注意,Spring中Bean的作用域可以分为Singleton、Prototype和其它,其中Singleton和Prototype是Spring框架原生支持的,其它作用域需要自行扩展,比如SpringWebMVC扩展了Session等作用域。所以你看下面的代码时也要在脑袋里把它们分成Singleton、Prototype和其它作用域,要不然你可能就被这很长很长的代码搞迷糊了
标签:Bean,生命,描述,BeanDefinition,代理 来源: