SpringBean的生命周期

206 阅读3分钟

一、Bean生命周期大致流程

  1. Bean的实例化
  2. Bean的属性赋值
  3. Bean的初始化
  4. Bean的使用
  5. Bean的销毁

二、Bean生命周期详细执行流程

SpringBean生命周期.png

1. 实例化bean

  • 根据配置情况调用构造方法或工厂方法实例化Bean。
    • 如xml、properties、yaml、注解等配置方式

2. 设置Bean属性值

  • 根据set方法、构造器或注解等对Bean设置属性值。

3. * 调用BeanNameAware的setBeanName()方法

  • 如果Bean实现了BeanNameAware接口,则Spring将调用Bean的setBeanName()方法传入当前Bean的 id值
  • BeanNameAware接口
    public interface BeanNameAware extends Aware {
      void setBeanName(String name);
    }
    
  • 传入,not设值,aware意为意识到,感知到,即实现该接口的Bean可以让Bean感知到/获取到其在Spring容器中的id属性值。

4. * 调用BeanFactoryAware的setBeanFactory()方法

  • 如果Bean实现了BeanFactoryAware接口的setBeanFactory()方法,则Spring将调用Bean的setBeanFactory()方法,传入当前 工厂实例的引用
  • BeanFactoryAware接口
    public interface BeanFactoryAware extends Aware {
      void setBeanFactory(BeanFactory beanFactory) throws BeansException;
    }
    
  • 实现该接口的 Bean 可以在 Bean 加载的过程中获取到加载该 Bean 的 BeanFactory。

5. * 调用ApplicationContextAware的setApplicationContext()方法

  • 如果Bean实现了ApplicationContextAware接口的setApplicationContext()方法,则Spring传入当前 ApplicationContext实例的引用
  • public interface ApplicationContextAware extends Aware {
      void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
    }
    
  • 实现该接口的Bean可以获取到 Spring 的 ApplicationContext,从而能够获取任意 Bean 及大量 IOC 容器信息。

6. * 调用BeanPostProcessor的预初始化方法

  • 如果BeanBeanPostProcessor相关联,则Spring将调用该接口的预初始化方法postProcessBeforeInitialization()对bean进行加工操作。这个非常重要,AOP就是用它实现的。
  • BeanPostProcessor接口
    public interface BeanPostProcessor {
      @Nullable
      default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          return bean;
      }
          
      @Nullable
      default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          return bean;
      }
    }
    

7. * 调用InitializingBean接口的afterPropertiesSet()方法

  • 如果Bean实现了InitializingBean接口,则Spring将调用该接口的afterPropertiesSet()方法。
  • InitializingBean接口
    public interface InitializingBean {
      void afterPropertiesSet() throws Exception;
    }
    

8. 调用自定义的初始化方法

  • 如果在配置文件中通过init-method属性指定了初始化方法,则调用该初始化方法。

9. * 调用BeanPostProcessor的后初始化方法

  • 如果有BeanPostProcessorBean相关联,则Spring将调用该接口的后初始化方法postProcessorAfterInitialization()方法。

10. Bean的使用

  • 此时,就可以使用Bean了。
  • 如果未指定/指定了Bean的生命周期为singleton,则将该Bean放入Spring IOC的缓冲池中,交由Spring管理该Bean的生命周期。
  • 如果指定了Bean的生命周期为prototype,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。

11. Bean的销毁

(1)如果Bean实现了DisposableBean接口,则Spring将调用该接口的destory()方法将Spring中的Bean销毁。

  • DisposableBean接口
    public interface DisposableBean {
      void destroy() throws Exception;
    }
    

(2)如果在配置文件中通过destory-method属性指定了Bean的销毁方法,则Spring将调用该方法销毁Bean。
(3)如果同时存在(1)(2),则先调用(1)再调用(2)。

三、其他

1. 为什么要实现各种aware接口?

  • Spring依赖注入的特点是无感知的。也就是说所有的Bean对Spring容器的存在是无感知的,并不清楚容器的存在。我们如果需要使用到Spring容器中的一些资源,就要让Bean主动意识到容器的存在,才能获取到容器中的一些资源。
  • BeanNameAware:获取容器中 Bean 的名称。
  • BeanFactoryAware:获取当前 BeanFactory,以便调用容器的服务/资源。
  • ApplicationContextAware:获取当前 ApplicationContext,以便调用容器的服务/资源。

2. 如果Bean实现了DisposableBean接口,也自定义了destory-method,那会执行两次desotry,销毁一次不就OK,两次销毁的意义?

  • I don't know.

参考:

  1. JavaEE企业级应用开发教程:Spring+SpringMVC+MyBatis / 黑马程序员编著
  2. c.biancheng.net/spring/life…
  3. www.zhihu.com/zvideo/1435…