深入了解Spring的Bean生命周期

目录
  • 源码下载
  • 什么是 Spring Bean 的生命周期
  • Bean的生命周期
    • Spring角度查看bean的定义与注册
    • SpringBoot角度查看bean定义和注册
  • 实例化,依赖注入,初始化
    • Bean的生命周期的扩展点
      • Bean级别
      • 容器级别
    • 常用接口
      • InstantiationAwareBeanPostProcessor
      • BeanNameAware
      • BeanFactoryAware
      • ApplicationContextAware
      • BeanPostProcessor
      • InitializingBean
      • DisposableBean
    • 常用注解
      • @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
      • @PostConstruct
      • @PreDestroy
    • 案例分析
      • 声明一个bean
      • Animal实现类
      • 我的服务类
      • 后置处理器
      • 工厂后置处理器
      • 输出结果和结果解读
    • Bean生命周期图

      源码下载

      本章节源码github

      什么是 Spring Bean 的生命周期

      对于普通的 Java 对象,当 new 的时候创建对象,然后该对象就能够使用了。一旦该对象不再被使用,则由 Java 自动进行垃圾回收。

      而 Spring 中的对象是 bean,bean 和普通的 Java 对象没啥大的区别,只不过 Spring 不再自己去 new 对象了,而是由 IoC 容器去帮助我们实例化对象并且管理它,我们需要哪个对象,去问 IoC 容器要即可。IoC 其实就是解决对象之间的耦合问题,Spring Bean 的生命周期完全由容器控制。

      Bean的生命周期

      Spring bean的生命周期阶段是:

      • 1.bean定义:就是从xml或注解定位资源加载读取bean的元信息并定义成一个BeanDefinition对象
      • 2.bean注册:将BeanDefinition对象根据相应的规则放到缓存池map中
      • 3.实例化:根据BeanDefinition实例化真正的bean,即是调用构造函数
      • 4.依赖注入:属性赋值调用setter方法,即是依赖注入(DI)
      • 5.初始化: 初始化是用户能自定义扩展的阶段
      • 6.销毁: 销毁是用户能自定义扩展的阶段

      注:其他都是在这阶段前后的扩展点

      Spring角度查看bean的定义与注册

      refresh()

      public void refresh() throws BeansException, IllegalStateException {
          synchronized(this.startupShutdownMonitor) {
              StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
               // 准备Bean初始化相关的环境信息,其内部提供了一个空实现的initPropertySources()方法用于提供给用户一个更改相关环境信息的机会
              this.prepareRefresh();
              // 创建BeanFactory实例,并且注册相关的bean信息
              ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
              // 注册Aware和Processor实例,并且注册了后续处理请求所需的一些Editor信息
              this.prepareBeanFactory(beanFactory);
      
              try {
                  // 提供的一个空方法,用于供给子类对已经生成的BeanFactory的一些信息进行定制
                  this.postProcessBeanFactory(beanFactory);
                  StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                  // 调用BeanFactoryPostProcessor及其子接口的相关方法,这些接口提供了一个入口,提供给了调用方一个修改已经生成的BeanDefinition的入口
                  this.invokeBeanFactoryPostProcessors(beanFactory);
                  // 对BeanPostProcessor进行注册
                  this.registerBeanPostProcessors(beanFactory);
                  beanPostProcess.end();
                  // 初始化国际化所需的bean信息
                  this.initMessageSource();
                  // 初始化事件广播器的bean信息
                  this.initApplicationEventMulticaster();
                  // 提供的一个空方法,供给子类用于提供自定义的bean信息,或者修改已有的bean信息
                  this.onRefresh();
                  // 注册事件监听器
                  this.registerListeners();
                   // 对已经注册的非延迟(配置文件指定)bean的实例化
                  this.finishBeanFactoryInitialization(beanFactory);
                  // 清除缓存的资源信息,初始化一些声明周期相关的bean,并且发布Context已被初始化的事件
                  this.finishRefresh();
              } catch (BeansException var10) {
                  if (this.logger.isWarnEnabled()) {
                      this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                  }
                   // 发生异常则销毁已经生成的bean
                  this.destroyBeans();
                  // 重置refresh字段信息
                  this.cancelRefresh(var10);
                  throw var10;
              } finally {
                  // 初始化一些缓存信息
                  this.resetCommonCaches();
                  contextRefresh.end();
              }
      
          }
      }

      SpringBoot角度查看bean定义和注册

      1. 自动加载配置类

      2. bean定义和注册

      注:springboot只是比spring多了自动配置相关流程,在spring上做了一层逻辑封装。

      实例化,依赖注入,初始化

      AbstractAutowireCapableBeanFactory为AutowireCapableBeanFactory接口的一个实现类,其中AbstractAutowireCapableBeanFactory实现类的一个方法doCreateBean()

      //位置:AbstractAutowireCapableBeanFactory#doCreateBean
      protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
          BeanWrapper instanceWrapper = null;
          if (mbd.isSingleton()) {
              instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
          }
      
          if (instanceWrapper == null) {
          	// 实例化阶段
              instanceWrapper = this.createBeanInstance(beanName, mbd, args);
          }
      
          ...
      
          Object exposedObject = bean;
      
          try {
          	// 依赖注入,属性赋值阶段
              this.populateBean(beanName, mbd, instanceWrapper);
              // 初始化阶段
              exposedObject = this.initializeBean(beanName, exposedObject, mbd);
          } catch (Throwable var18) {
              ...
          }
      
          ...
      }

      可以发现,分别调用三种方法:

      • createBeanInstance() -> 实例化
      • populateBean() -> 依赖注入
      • initializeBean() -> 初始化

      销毁

      销毁阶段是在容器关闭时调用的,在ConfigurableApplicationContext#close()

      至于xxxAware,BeanPostProcessor,BeanFactoryPostProcessor等类,只不过是对主流程的一系列扩展点而已。

      Bean的生命周期的扩展点

      Spring Bean 的生命周期的扩展点很多,这里不可能全部列出来,只说核心的扩展点。这也就是为什么 Spring 的扩展性很好的原因,开了很多的口子,尽可能让某个功能高内聚松耦合,用户需要哪个功能就用哪个,而不是直接来一个大而全的东西。

      Bean级别

      这些接口的实现类是基于 Bean 的,只要实现了这些接口的Bean才起作用。

      • BeanNameAware
      • BeanFactoryAware
      • ApplicationContextAware
      • InitializingBean
      • DisposableBean

      还要很多的xxxAware,这些不常用,下面生命周期测试就不加上,如:

      • BeanClassLoaderAware
      • EnvironmentAware
      • EmbeddedValueResolverAware
      • ResourceLoaderAware
      • ApplicationEventPublisherAware
      • MessageSourceAware
      • ServletContextAware

      容器级别

      这些接口的实现类是独立于 Bean 的,并且会注册到 Spring 容器中。一般称它们的实现类为后置处理器。

      在 Spring 容器创建任何 Bean 的时候,这些后置处理器都会发生作用

      BeanPostProcessor

      InstantiationAwareBeanPostProcessor(InstantiationAwareBeanPostProcessor 是继承了 BeanPostProcessor)

      工厂后处理器接口也是容器级的。在应用上下文装配配置文件之后立即调用:

      • AspectJWeavingEnabler
      • ConfigurationClassPostProcessor
      • CustomAutowireConfigurer

      常用接口

      InstantiationAwareBeanPostProcessor

      该类是 BeanPostProcessor 的子接口,常用的有如下三个方法:

      • postProcessBeforeInstantiation(Class beanClass, String beanName):在bean实例化之前调用
      • postProcessProperties(PropertyValues pvs, Object bean, String beanName):在bean实例化之后、设置属性前调用
      • postProcessAfterInstantiation(Class beanClass, String beanName):在bean实例化之后调用

      BeanNameAware

      BeanNameAware接口是为了让自身Bean能够感知到,只有一个方法setBeanName(String name),获取到自身在Spring容器中的id或name属性。

      BeanFactoryAware

      该接口只有一个方法setBeanFactory(BeanFactory beanFactory),用来获取当前环境中的 BeanFactory,可以对工厂中的所有bean进行扩展。

      ApplicationContextAware

      该接口只有一个方法setApplicationContext(ApplicationContext applicationContext),用来获取当前环境中的 ApplicationContext,可以对整个容器进行扩展。

      注:有时候并不会调用该接口,这要根据你的IOC容器来决定:Spring IOC容器最低要求是实现BeanFactory接口,而不是实现ApplicationContext接口,对于那些没有实现ApplicationContext接口的容器,在生命周期对应的ApplicationContextAware定义的方法也是不会调用的,只要实现了ApplicationContext接口的容器,才会调用。

      BeanPostProcessor

      postProcessBeforeInitialization(Object bean, String beanName):在初始化之前调用此方法,Spring 的 AOP 就是利用它实现的。

      postProcessAfterInitialization(Object bean, String beanName):在初始化之后调用此方法

      InitializingBean

      该接口只有一个方法afterPropertiesSet(),在属性注入完成后调用。

      凡是继承该接口的类,在初始化bean的时候都会执行该方法,可以进行一些属性配置等工作。

      InitializingBean 对应生命周期的初始化阶段,在源码的invokeInitMethods(beanName, wrappedBean, mbd)方法中调用。

      DisposableBean

      该接口的作用是在对象销毁时调用,可以做一些资源销毁操作。

      DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法

      常用注解

      @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")

      @Bean声明一个bean,配合@Configuration注解使用

      initMethod:声明bean初始化时回调一个方法,该方法需要程序员编写

      destroyMethod:声明bean销毁时回调一个方法,该方法需要程序员编写

      @PostConstruct

      bean的一个基于注解的初始化方法

      @PreDestroy

      bean的一个基于注解的销毁方法

      案例分析

      声明一个bean

      @Configuration
      public class BeanInitAndDestroyConfig {
      
          /**
           * @return 这里没有指定bean名字,默认是方法名
           */
          @Description("测试bean的生命周期")
          @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
          public MyService myServiceBeanName() {//入参数可注入其他依赖
              return new MyService();
          }
      }
      • 声明一个名为:myServiceBeanName的bean
      • initMethod:bean的初始化方法为:initMethod
      • destroyMethod:bean的销毁方法为:destroyMethod

      Animal实现类

      这里只是想用来说明 @Qualifier注解能根据bean名称匹配。

      我的服务类

      即是针对当前bean只调用一次的接口

      /**
       * @Description: bean生命周期测试:这些接口只针对当前bean
       * @Author: jianweil
       * @date: 2025/12/8 9:46
       */
      public class MyService implements Person, BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
      
          private Animal animal = null;
      
          private ApplicationContext applicationContext;
      
          /**
           *接口规定方法
           */
          @Override
          public void service() {
              this.animal.use();
          }
      
          public MyService() {
              System.out.println("2. [bean实例化]:"+this.getClass().getSimpleName()+"----------构造方法");
          }
          /**
           *接口规定方法:注入依赖
           */
          @Override
          @Autowired
          @Qualifier("dog")
          public void setAnimal(Animal animal) {
              System.out.println("5. [bean属性赋值]:dog----依赖注入");
              this.animal = animal;
          }
      
      
          @Override
          public void setBeanName(String s) {
              System.out.println("6. 调用【BeanNameAware】--setBeanName:"+s);
      
          }
      
          @Override
          public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
              System.out.println("7. 调用【BeanFactoryAware】--setBeanFactory");
          }
      
      
          @Override
          public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
              this.applicationContext = applicationContext;
              System.out.println("8. 调用【ApplicationContextAware】--setApplicationContext");
      
          }
      
          /**
           * 初始化1
           */
          @PostConstruct
          public void myInit() {
              System.out.println("10. [初始化] 注解@PostConstruct自定义初始化方法[myInit]");
          }
      
          /**
           * 初始化2
           */
          @Override
          public void afterPropertiesSet() throws Exception {
              System.out.println("11. [初始化] 接口InitializingBean方法[afterPropertiesSet]");
      
          }
      
          /**
           * 初始化3
           */
          public void initMethod() {
              System.out.println("12. [初始化] 注解@Bean自定义初始化方法[initMethod]");
          }
      
          /**
           * 销毁1
           */
          @PreDestroy
          public void myDestroy() {
              System.out.println("14. [销毁] 注解@PreDestroy自定义销毁方法[myDestroy]");
          }
      
          /**
           * 销毁2
           */
          @Override
          public void destroy() throws Exception {
              System.out.println("15. [销毁] 接口DisposableBean方法[destroy]");
          }
      
          /**
           * 销毁3
           */
          public void destroyMethod() {
              System.out.println("16. [销毁] 注解@Bean自定义销毁方法[destroyMethod]");
          }
      }

      这里实现的接口只作用于当前bean(即是上面@bean定义的bean名为myDefineBeanName)生命周期

      后置处理器

      每个bean生命周期都执行一次

      后置处理器是作用于ioc容器中所有bean的生命周期。

      /**
       * @Description: todo
       * @Author: jianweil
       * @date: 2025/12/20 17:20
       */
      @Component
      public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
          @Override
          public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
              if ("myServiceBeanName".equals(beanName) || "dog".equals(beanName)) {
                  System.out.println("============================InstantiationAwareBeanPostProcessor-开始======================");
                  System.out.println("1. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() 方法:beanName为"+beanName);
              }
              return null;
          }
      
          @Override
          public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
              if ("myServiceBeanName".equals(beanName) || "dog".equals(beanName)) {
                  System.out.println("3. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() 方法:beanName为"+beanName);
              }
              return true;
          }
      
          @Override
          public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
              if ("myServiceBeanName".equals(beanName) || "dog".equals(beanName)) {
                  System.out.println("4. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessProperties() 方法:beanName为"+beanName);
                  System.out.println("============================InstantiationAwareBeanPostProcessor-结束======================");
      
              }
              return null;
          }
      }
      /**
       * @Description: 后置bean的初始化器:所有的bean都会拦截执行
       * @Author: jianweil
       * @date: 2025/12/8 9:46
       */
      @Component
      public class MyBeanPostProcessor implements BeanPostProcessor {
          @Override
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
              //这里过滤掉springboot自动配置的bean,只打印我们项目的bean情况
              if ("myServiceBeanName".equals(beanName) || "dog".equals(beanName)) {
                  System.out.println("9. [容器级别每个bean都回调] 调用 BeanPostProcessor.postProcessBeforeInitialization 方法:beanName为" + beanName);
              }
      
              return bean;
          }
      
          @Override
          public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
              if ("myServiceBeanName".equals(beanName) || "dog".equals(beanName)) {
                  System.out.println("13. [容器级别每个bean都回调] 调用 BeanPostProcessor.postProcessAfterInitialization 方法:beanName为" + beanName);
              }
              return bean;
          }
      }

      工厂后置处理器

      容器级别,只允许一次

      @Component
      public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              System.out.println("0. [容器级别只调用一次] 调用 BeanFactoryPostProcessor.postProcessBeanFactory() 方法");
          }
      }

      输出结果和结果解读

      “//”标记为解读

      //容器级别的工厂后置处理器,只在应用上下文装配配置文件之后立即调用1次
      0. [容器级别只调用一次] 调用 BeanFactoryPostProcessor.postProcessBeanFactory() 方法
      
      
      //因为我们生命过程只打印("myServiceBeanName".equals(beanName) || "dog".equals(beanName)),所有猫只有构造方法打印了
      猫----------构造方法
      
      //###############################dog的生命周期###############################################
      //后置处理器,容器级别,作用于所有bean
      ============================InstantiationAwareBeanPostProcessor-开始======================
      1. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() 方法:beanName为dog
      //狗的实例化
      狗----------构造方法
      //后置处理器,容器级别,作用于所有bean
      3. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() 方法:beanName为dog
      //后置处理器,容器级别,作用于所有bean
      4. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessProperties() 方法:beanName为dog
      ============================InstantiationAwareBeanPostProcessor-结束======================
      //后置处理器,容器级别,作用于所有bean
      9. [容器级别每个bean都回调] 调用 BeanPostProcessor.postProcessBeforeInitialization 方法:beanName为dog
      //后置处理器,容器级别,作用于所有bean
      13. [容器级别每个bean都回调] 调用 BeanPostProcessor.postProcessAfterInitialization 方法:beanName为dog
      //###############################dog的bean完成,开始myServiceBeanName###############################################
      
      
      //后置处理器,容器级别,作用于所有bean
      ============================InstantiationAwareBeanPostProcessor-开始======================
      1. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() 方法:beanName为myServiceBeanName
      
      //实例化
      2. [bean实例化]:MyService----------构造方法
      
      //后置处理器,容器级别,作用于所有bean
      3. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() 方法:beanName为myServiceBeanName
      //后置处理器,容器级别,作用于所有bean
      4. [容器级别每个bean都回调] 调用 InstantiationAwareBeanPostProcessor.postProcessProperties() 方法:beanName为myServiceBeanName
      ============================InstantiationAwareBeanPostProcessor-结束======================
      
      //属性赋值,即是依赖注入
      5. [bean属性赋值]:dog----依赖注入
      
      //bean级别,bean:myServiceBeanName实现了接口BeanNameAware
      6. 调用【BeanNameAware】--setBeanName:myServiceBeanName
      //bean级别
      7. 调用【BeanFactoryAware】--setBeanFactory
      //bean级别
      8. 调用【ApplicationContextAware】--setApplicationContext
      
      //后置处理器,容器级别,作用于所有bean:初始化前处理
      9. [容器级别每个bean都回调] 调用 BeanPostProcessor.postProcessBeforeInitialization 方法:beanName为myServiceBeanName
      
      //初始化
      10. [初始化] 注解@PostConstruct自定义初始化方法[myInit]
      11. [初始化] 接口InitializingBean方法[afterPropertiesSet]
      12. [初始化] 注解@Bean自定义初始化方法[initMethod]
      
      //后置处理器,容器级别,作用于所有bean:初始化后处理
      13. [容器级别每个bean都回调] 调用 BeanPostProcessor.postProcessAfterInitialization 方法:beanName为myServiceBeanName
      
      //容器环境加载完成,这时可以使用所有bean
      2025-12-21 11:18:42.994  INFO 18956 --- [           main] c.l.s.SpringbootBeanLifecycleApplication : Started SpringbootBeanLifecycleApplication in 0.719 seconds (JVM running for 1.312)
      
      //销毁
      14. [销毁] 注解@PreDestroy自定义销毁方法[myDestroy]
      15. [销毁] 接口DisposableBean方法[destroy]
      16. [销毁] 注解@Bean自定义销毁方法[destroyMethod]
      
      Process finished with exit code 0
      

      Bean生命周期图

      了解 Spring 生命周期的意义就在于,可以利用 Bean 在其存活期间的指定时刻完成一些相关操作。一般情况下,会在 Bean 被初始化后和被销毁前执行一些相关操作。

      以上就是深入了解Spring的Bean生命周期的详细内容,更多关于Spring Bean生命周期的资料请关注其它相关文章!

      本文转自网络,如有侵权请联系客服删除。