一、什么是Spring Bean生命周期?
Spring Bean生命周期是指从Bean的创建到销毁的整个过程,其中涉及到Spring容器对Bean的一系列处理操作,包对Bean的实例化、依赖注入、初始化和销毁。Spring框架中Bean的生命周期主要包括以下关键步骤:
- 实例化Bean:Spring容器根据Bean的定义从容器中取出Bean的类,通过反射机制进行实例化。
- 属性填充:Spring容器从Bean定义中获取属性值,将这些属性值注入到新创建的Bean实例中,这个过程也叫做依赖注入。
- Aware接口回调:如果Bean涉及到实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口,则会触发BeanNameAware.setBeanName、BeanClassLoaderAware.setBeanClassLoader、BeanFactory.setBeanFactory方法的调用。
- BeanPostProcessor接口回调:触发前置方法BeanPostProcessor.postProcessBeforeInitialization。注意的是ApplicationContextAwareProcessor和InitDestroyAnnotationBeanPostProcessor都是BeanPostProcessor的实现类,因此可能触发ApplicationContextAware的setApplicationContext方法回调和init-Method回调。
- InitializingBean接口回调:触发InitializingBean.afterPropertiesSet方法。
- BeanPostPorcessor接口回调:触发后置方法BeanPostProcessor.postProcessAfterInitialization方法。
- Bean初始化完成,可以投入使用
- 当Bean实现了DisposableBean接口时,Spring容器关闭时,会回调DisposableBean.destory方法。
- Bean被销毁,生命周期结束。
工作流程图:
二、Bean生命周期执行流程验证
1.编写测试代码验证结果
定义一个LifeCycleBean类,将其作为SpringBean进行管理,让其实现BeanNameAware, BeanFactoryAware, BeanPostProcessor, ApplicationContextAware, InitializingBean, DisposableBean接口,在实现方法中打印对应的信息,查看方法调用的顺序。
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, BeanPostProcessor, ApplicationContextAware, InitializingBean, DisposableBean {
//前置处理是否被调用标识
private volatile boolean beforeInitializationInvoked = false;
//后置处理是否被调用标识
private volatile boolean afterInitializationInvoked = false;
@Override
public void setBeanName(String name) {
System.out.println("BeanNameAware.name be invoked");
}
@PostConstruct
public void init() {
System.out.println("PostConstruct.init be invoked");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean.destroy be invoked");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet be invoked");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware.setApplicationContext be invoked");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!beforeInitializationInvoked) {
beforeInitializationInvoked = true;
System.out.println("BeanPostProcessor.postProcessBeforeInitialization be invoked");
}
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (!afterInitializationInvoked) {
afterInitializationInvoked = true;
System.out.println("BeanPostProcessor.postProcessAfterInitialization be invoked");
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware.setBeanFactory be invoked");
}
}
启动项目,查看控制台打印结果如下:
关闭容器后,控制台打印如下:
因此可以得出,Bean启动后,初始化的执行顺序是:BeanNameAware->BeanFactoryAware->ApplicationContextAware(由ApplicationContextAwareProcessor调用)->PostConstruct(由InitDestroyAnnotationBeanPostProcessor调用)->BeanPostProcessor.postProcessBeforeInitialization(自定义)->InitializingBean.afterPropertiesSet->BeanPostProcessor.postProcessAfterInitialization–>DisposableBean.destory。
2.源码追溯Bean初始化回调过程
通过断点可以得出Bean初始化的入口在AbstractAutowireCapableBeanFactory.initializeBean方法。
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()) {
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的命名十分明显,用于调用一些Aware接口的实现类,进入invokeAwareMethods方法后,通过判断当前bean是否为Aware类型,如果是则进一步判断是Aware接口下的哪一种类型,然后进行类型转换调用对应的方法。
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);
}
}
}
执行完invokeAwareMethods后,则调用initializeBean方法中的applyBeanPostProcessorsBeforeInitialization方法,通过遍历现有的BeanPostProcessor类,依次调用其postProcessBeforeInitialization方法。
@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;
}
其中重点关注ApplicationContextAwareProcessor和InitDestroyAnnotationBeanPostProcessor两个类,他们都属于BeanPostPorcessor的实现类,因此在循环时都会调用其postProcessBeforeInitialization方法。ApplicationContextAwareProcessor.postProcessBeforeInitialization方法中有一个比较重要的方法invokeAwareInterfaces,该方法也是用于回调一些实现了Aware接口的类。其中ApplicationContextAware.setApplicationContext就是在此处被调用,当然还涉及到EnvironmentAware、EmbeddedValueResolverAware、MessageSourceAware等的回调。
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);
}
}
InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization方法重要是通过反射机制调用被注释PostConstruct修饰的init-Method.
在完成applyBeanPostProcessorsBeforeInitialization调用后,则会调用invokeInitMethods方法, 如果Bean实现了InitializingBean接口,Spring容器会调用其afterPropertiesSet()方法。
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
最调用applyBeanPostProcessorsAfterInitialization方法,通过遍历BeanPostProcessor的实现类,调用其postProcessAfterInitialization后置方法。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}