Spring Bean生命周期是Spring中重要知识点,对于Bean的拓展十分重要。但想要完全记住整个生命周期并不容易,本文从源码入手解析Spring Bean的生命周期,结合示意图,比较容易记忆。
首先,为方便记忆,将Bean的生命周期主要分为四个阶段,然后在这四个阶段之间穿插各种拓展点。
四类基本生命周期
这四类分别是:
- Instantiation 实例化
- Populate 属性赋值
- Initialization 初始化
- Destruction 销毁
源码的入口在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory类的doCreateBean方法。
// 忽略无关代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......
// Instantiate the bean.
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
......
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
......
}
其中第一阶段实例化Bean对应createBeanInstance(beanName, mbd, args)
方法, 第二阶段属性赋值对应populateBean(beanName, mbd, instanceWrapper)
, 第三阶段对应方法initializeBean(beanName, exposedObject, mbd)
,至于第四阶段Bean的销毁是在容器关闭时调用的,详见ConfigurableApplicationContext#close()
。
看一下populateBean(beanName, mbd, instanceWrapper)
函数源码
// 忽略无关代码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
......
if (pvs != null) {
// 属性赋值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
第一类拓展点 InstantiationAwareBeanPostProcessor
可以看到,在第一阶段实例化Bean和第二阶段属性赋值之前,会调用所有InstantiationAwareBeanPostProcessor
类的postProcessAfterInstantiation(Object bean, String beanName)
方法, 改变Bean的状态。
InstantiationAwareBeanPostProcessor
继承至接口BeanPostProcessor
, 和postProcessAfterInstantiation(Object bean, String beanName)
相呼应的还有一个方法是postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
,从名字上可以看出,应该是在实例化Bean之前执行。
这部分代码在调用doCreateBean方法的createBean方法中
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
}
......
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
return beanInstance;
}
protectedObject resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
可以看到,postProcessBeforeInstantiation在doCreateBean之前调用,也就是在bean实例化之前调用的,英文源码注释解释道该方法的返回值会替换原本的Bean作为代理,这也是Aop等功能实现的关键点。
所以这里归纳出第一类拓展点InstantiationAwareBeanPostProcessor
, 这些接口会切入到多个Bean的生命周期中,并在实例化Bean前后完成Aop,状态改变等功能。
看下初始化阶段initializeBean
方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
.......
invokeAwareMethods(beanName, bean);
......
if (mbd == null || !mbd.isSynthetic()) {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
会先调用invokeAwareMethods
方法,然后再调用applyBeanPostProcessorsBeforeInitialization
, 再调用invokeInitMethods
方法进行初始化,最后调用applyBeanPostProcessorsAfterInitialization
方法。
invokeInitMethods
方法会判断Bean是否实现了InitializingBean
接口,如果是,则调用InitializingBean
接口的afterPropertiesSet()方法进行初始化,然后再使用invokeCustomInitMethod(beanName, bean, mbd)
方法调用用户自定义的Bean初始化方法。
第二类拓展点 Aware Group One
但在初始化之前会先调用invokeAwareMethods
方法和applyBeanPostProcessorsBeforeInitialization
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);
}
}
}
从代码可以归纳出第二类拓展点Aware Group One,让Bean感知BeanName,BeanClassLoader, BeanFactory。
为什么这里是Group One,因为后面还有Aware Group Two。
第三类拓展点 BeanPostProcessor
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
该方法调用所有BeanPostProcessor
的postProcessBeforeInitialization
与InstantiationAwareBeanPostProcessor
一样,和postProcessBeforeInitialization
对应的还有一个postProcessAfterInitialization
,从方法名也可以看出这个方法应该是在初始化阶段完成后执行。applyBeanPostProcessorsAfterInitialization
方法会调用所有BeanPostProcessor
的postProcessAfterInitialization
方法。
所以这里归纳出第三个扩展点,在实例化前后会分别调用BeanPostProcessor
的postProcessBeforeInitialization
方法和applyBeanPostProcessorsAfterInitialization
方法。
第四类拓展点 Aware Group Two
还有Aware Group Two呢?
在Spring容器中一个BeanPostProcessor
,ApplicationContextAwareProcessor
,它的postProcessBeforeInitialization
方法如下
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
......
invokeAwareInterfaces(bean);
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
从上面可以归纳出第四类拓展点Aware Group Two, 它会让Bean感知Environment, EmbeddedValueResolver, ResourceLoader, ApplicationEventPublisher, MessageSource, ApplicationContext。
最后归纳如下图