文章
问答
冒泡
跟着源码看spring bean的生命周期

前言

我们都知道,spring 已经成为了java实际上的基础。大多数时候,我们在开发过程中更多的是面向spring的编程,那么spring bean 的生命周期,基本也出成为了面试的必考项。本文,对照源码把spring bean的生命周期梳理下。
version: spring boot 2.6.3
 
我们将bean的生命周期,梳理得到如下图
 
 
 
1.spring boot 执行run之后,开始进行各种准备工作,这个内容可以在 SpringApplication#run 中看到。
在prepareContext 这个环节,对spirng boot的启动类进行处理,包括启动类上的注解处理,对context进行装配初始化赋值等等,例如beanFactory,beanFactoryPostProcessor
 
下面进入refreshContext这个环节,这里是对bean处理的主要环节。代码位于 AbstractApplicationContext#refresh 在这里,我们可以看到bean的整个装配过程。
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end();

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
         contextRefresh.end();
      }
   }
}
beanDefinition的处理主要在 invokeBeanFactoryPostProcessors 这一步中。追溯代码到 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 在这一步中,通过ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry 来处理beanDefinition的注册,代码追溯 ConfigurationClassParser#parse-> ClassPathBeanDefinitionScanner#doScan ,在这个doScan方法中,完成了对符合实例化条件的class的beanDefinition注册。
 
在beanDefinition完成注册之后,已经具备了实例化bean的物料。下面就可以开始进行实例化。主要代码依旧在 PostProcessorRegistrationDelegate#finishBeanFactoryInitialization 由代码可以看到,spring讲需要实例化的class 分成了三个优先级
  • priorityOrderedPostProcessors PriorityOrdered 类型的
  • orderedPostProcessorNames Ordered类型的
  • nonOrderedPostProcessorNames
invokeBeanFactoryPostProcessors 中,主要完成了beanDefinition注册以及BeanFactoryPostProcessor实现类的实例化。而普通单例bean的实例化主要在finishBeanFactoryInitialization中去完成。
 
我们通过代码追溯,可以看到 bean的实例化过程,主要是在 AbstractAutowireCapableBeanFactory#createBean 完成的。
主要步骤如下
创建Bean的实例
AbstractAutowireCapableBeanFactory#createBeanInstance
设置对象属性
AbstractAutowireCapableBeanFactory#populateBean
初始化Bean
AbstractAutowireCapableBeanFactory#initializeBean
处理各种Aware接口的实现(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware)
AbstractAutowireCapableBeanFactory#invokeAwareMethods
BeanPostProcess前置处理
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
执行init方法(如果是InitializingBean)
AbstractAutowireCapableBeanFactory#invokeInitMethods
-- 执行自定义的init方法(如果有)
AbstractAutowireCapableBeanFactory#invokeCustomInitMethod
BeanPostProcess后置处理
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
注册DisposableBean(如果需要)
AbstractBeanFactory#registerDisposableBeanIfNecessary
-- 注册到DisposableBean(是单例)
DefaultSingletonBeanRegistry#registerDisposableBean
-- 注册DestructionCallback(非单例)
registerDestructionCallback
bean的使用
销毁Bean
DefaultSingletonBeanRegistry#destroyBean
 
我们来写一个类来测试一下
@Component
public class BeanComponent implements ApplicationContextAware, BeanNameAware, BeanFactoryAware, BeanFactoryPostProcessor, BeanPostProcessor, EnvironmentAware, InitializingBean, DisposableBean {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware-> setApplicationContext");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware-> setBeanName");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor-> postProcessBeanFactory");
    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("EnvironmentAware-> setEnvironment");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean-> afterPropertiesSet");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean-> destroy");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware-> setBeanFactory");
    }
}
打印的内容如下
BeanNameAware-> setBeanName
BeanFactoryAware-> setBeanFactory
EnvironmentAware-> setEnvironment
ApplicationContextAware-> setApplicationContext
InitializingBean-> afterPropertiesSet
BeanFactoryPostProcessor-> postProcessBeanFactory
Disconnected from the target VM, address: '127.0.0.1:58617', transport: 'socket'
2022-03-18 19:25:19.190  INFO 39144 --- [           main] ms.bean.BeanApp                          : Started BeanApp in 1324.59 seconds (JVM running for 1325.557)
DisposableBean-> destroy
这样,可以比较直观的看到bean生命周期的一个顺序。
 
根据上面所述,我们可以根据bean的生命周期的执行,在其中添加一些我们的处理逻辑。
如果是要动态创建bean 并且被其他的bean依赖注入,应该使用BeanFactoryPostProcessor的实现类来做,这样,才能保证这个bean在最先执行。
@RequiredArgsConstructor
@Configuration
public class BeanConfiguration implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        GenericApplicationContext genericApplicationContext = new GenericApplicationContext((DefaultListableBeanFactory) beanFactory);
        genericApplicationContext.registerBean(UserComponent.class);
    }
}
以上,就是跟着源码所见的spring bean的生命周期梳理。
spring
bean

关于作者

落雁沙
非典型码农
获得点赞
文章被阅读