我们就从最先执行的setBeanName开始一览,spring bean 的生命周期
setBeanName 的执行流程
先看一波 debug 栈的截图
先是registerBeanPostProcessors
这个都熟悉,接下来是 getBean相关的,不关心,我们关心初始化的时候干了嘛,那就从 createBean 开始看起,一定要记着这个时候类的构造方法已经调用过了哦。
createBean
方法开始有很多 check ,接着下面这句,猜测是跟代理初始化相关的,我们没添加代理,先放过
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
然后,进入doCreateBean
方法,这个方法我们还是直奔 debug 指示的initializeBean
方法,其中1783 行的invokeAwareMethods
方法里面执行了我们关心的setBeanName
方法。仔细的浏览一下这个方法:
private void invokeAwareMethods(final String beanName, final 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);
}
}
}
同时发现不仅setBeanName
在这里执行,还有setBeanClassLoader
和setBeanFactory
也是在这里执行的。
再回到doCreateBean
方法,往下翻会发现下面这行
// Register bean as disposable.
registerDisposableBeanIfNecessary(beanName, bean, mbd);
点进去看看这里面其实会注册 DisposableBean interface, 自定义的 destroy method。
而这些都是在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
这个类里面
setApplicationContext执行流程
再看看setApplicationContext
的执行流程和 setBeanName
有何不同
同样的也是从registerBeanPostProcessors
开始,一直到initializeBean
,和上面的 setBeanName 都是一样的,只不过这次是到了 1788 行的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
方法,看看这个方法实现
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;
}
从 getBeanPostProcessors()
取出所有的BeanPostProcessor
然后对当前的 bean 执行所有的 processor。即初始化每个 bean 的时候都会经历所有的BeanPostProcessor
。
再看看上面的截图,自定义的setApplicationContext
是在
org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization
中执行的,
但是ApplicationContextAwareProcessor是什么时候注入的, 点击引用,发现是在,org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 中手动注入的,按下不表。
回到ApplicationContextAwareProcessor.invokeAwareInterfaces
方法,看看有哪些 Aware 接口可以执行:
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 接口都是可以自定义的。
在回头看看org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean()
方法,你会发现初始化的扩展点几乎都在这里执行的,相关代码都加上了注释。这下找到源头不怕记不住了。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 1. setBeanName、setBeanClassLoader、setBeanFactory 方法执行
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2. BeanPostProcessor.postProcessBeforeInitialization 方法执行
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3. afterPropertiesSet 和 定制的 init-method 执行
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()) {
// 4. BeanPostProcessor.postProcessAfterInitialization 方法执行
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
,似乎还漏了点东西。注解!!
@PostConstruct 注解
是不是和上面的流程是一样的,这次只不过是用InitDestroyAnnotationBeanPostProcessor
来负责注解的初始化方法执行,只不过这个 processor 的注入是在AnnotatedBeanDefinitionReader
初始化的时候。至于先后顺序的话,一向都是注解优先的,这次也不会例外。
可以推断一下实现上是如何让注解优先执行的?
我们在文档中读到了一个接口Ordered,用来指定优先级的,注解的InitDestroyAnnotationBeanPostProcessor
就实现了这个接口的增强接口PriorityOrdered
,由此确保了@PostConstruct
的执行顺序。
初始化相关的几乎都在这里了,总结一下,IOC 容器相关的会先执行,例如 setBeanName,setBeanFactory 等等,接下来的初始化方法都是由内置的BeanPostProcessor-before的实现类的初始化方法,例如 setApplicationContext、postProcessBeforeInitialization、以及注解@PostConstruct;接着是 initMethod 相关方法执行;然后postProcessAfterInitialization 的处理;初始化结束。
这里需要注意的一个点是:如果一个类同时实现了BeanPostProcessor 、InitializingBean,在 getBean 的时候你会发现,哎,先执行了InitializingBean.afterPropertiesSet() 然后才是
BeanPostProcessor.postProcessBeforeInitialization() ,那是什么原因呢,因为BeanPostProcessor是相对于其他 bean 而言的,而InitializingBean确是对当前实例对象的。如果 类A 实现了BeanPostProcessor,类B实现了InitializingBean,那么类 A 的BeanPostProcessor肯定是在类 B 的初始化过程执行 InitializingBean方法之前执行的。
至于销毁,我们在上面看到了是在AbstractAutowireCapableBeanFactory#doCreateBean
里面注册的销毁方法,同理@PreDestroy优先。调用时机当然是在容器销毁的时候。至于为什么@PreDestroy可以先执行,也是上面的原因,InitDestroyAnnotationBeanPostProcessor
实现了DestructionAwareBeanPostProcessor
接口,bean销毁时,也会执行一遍所有的销毁 processor,当然就执行到了@PreDestroy注解的方法。
到这里bean生命周期的大部分就结束了。
附上测试代码
@Component
public class ThingOne implements BeanFactoryAware, ApplicationContextAware,BeanPostProcessor, InitializingBean {
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("invoke setBeanFactory()");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("invoke setApplicationContext()");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(this.getClass().getName() + " invoke postProcessBeforeInitialization() to bean:"+bean.getClass().getName()+", beanName:"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(this.getClass().getName() + " invoke postProcessAfterInitialization() to bean:"+bean.getClass().getName()+", beanName:"+beanName);
return bean;
}
//1 PostConstruct
@PostConstruct
public void postConstructMethod(){
System.out.println(this.getClass().getName() + " 执行 PostConstruct " +"postConstructMethod");
}
@PreDestroy
public void preDestroyMethod(){
System.out.println(this.getClass().getName() + " 执行 @PreDestroy " +"preDestroyMethod");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(this.getClass().getName() + " 执行 InitializingBean 接口 "+ "afterPropertiesSet");
}
}
/*-------------------------------------------------------------------------*/
@Component
public class ThingTwo implements InitializingBean{
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(this.getClass().getName() + " 执行 InitializingBean 接口 "+ "afterPropertiesSet");
}
}
/*-------------------------------------------------------------------------*/
@Configuration
@ComponentScan(basePackages = "org.lifecycle.demo")
public class LifecycleCallbackDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifecycleCallbackDemo.class);
System.out.println(applicationContext.getBean("someThing"));
applicationContext.close();
}
}