Spring 中 Bean 的生命周期

以下内容只是为了方便对 Bean 的生命周期的记忆。很多概念并不严谨,甚至可能不正确。

Spring  中 Bean 的生命周期中存在4个时期:

1: Bean 的 Construct

2: Bean  属性的 Inject

3: Bean 的 Init

4: Bean 的 destroy

也就是说,Spring 中的 Bean 先被 Contrust ,然后根据需要对属性进行 Inject ,然后才会执行初始化操作(很是不解为什么 Spring 要把初始化放到 Inject 的后面。),最后进行 destroy 。如果某个 Bean 被配置为 prototype ,那么在 Spring 对该 Bean 实例进行了 init  操作后将会把该实例的管理权交给 developter 。也就是说该实例在 Spring 中不具有 destroy 时期。但在此为可将 Bean 认为是 singleton ,因为需要对 Bean 的 destroy  时期也进行总结。

在这4个时期中,Bean  在不同的配置和环境中所展现的生命周期是不同的。但无论环境如何变化,所有的 Bean 都存在一个基本的生命周期,即 Construct  时期 Bean 的 Constructor 的调用,以及 Inject  时期 setter 的调用。但为了便于记忆,将假设在 Bean 的配置文件中都会配置一个 init-method 和 destroy-method 属性。这样“基本的生命周期”就是:

Construct  时期 : Constructor 的调用

Inject 时期 : setter 的调用

Init 时期 : init-method 的调用

destroy 时期 : destroy-mehtod 的调用

以下将以基于这个基本的生命周期进行扩展(整个生命周期分为4个时期,共13步):

 Construct 时期:

    基本的是对 Constructor 的调用,但是在 Constructor 的调用前后可以存在额外的生命周期。即在 Constructor 调用前,可以存在一个 before  操作,之后可以存在一个 after  的操作。实现方法是将 InstantiationAwareBeanPostProcessor 的实例注册打 BeanFactory 中。该接口中的 postProcessBeforeInstantiation 方法将在Constructor 调用前被执行。postProcessAfterInstantiation 方法将在Constructor 调用后执行。要说明的是该接口中的 postProcessPropertyValues 方法,从方法名上看它应该是和属性相关,似乎应该将它分在 Inject 时期,但是因为它在 InstantiationAwareBeanPostProcessor 接口内定义,为了记忆,所以也将其分在 Construct 时期,该方法是该时期最后执行的方法,即在 postProcessAfterInstantiation 后被执行。(InstantiationAwareBeanPostProcessor  是一个接口,但是它存在一个适配器:InstantiationAwareBeanPostProcessorAdapter 如果要实现这个功能可以考虑从这个适配器继承)

    这样一来Constructor 时期的生命周期有4步,为:

               01: InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation  方法的调用

               02: Bean 的 Construct 的调用

               03: InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation  方法的调用

               04: InstantiationAwareBeanPostProcessor#postProcessPropertyValues 方法的调用


 Inject 时期:

    基本的是根据配置文件中对属性的配置进行 setter 操作。但在这个时期还可以存在两个接口注入。即如果 Bean 实现了 BeanNameAware 接口,那么 BeanNameAware#setBeanName 方法将被调用。如果 Bean 实现了 BeanFactoryAware 接口,那么 BeanFactoryAware#setBeanFactory 方法将被调用。如果同时实现了这两个接口setBeanName 方法在 setBeanFactory 方法前调用。

    这样一来 Inject 时期 Bean 的生命周期有3步,为:

                05: setter 方法的调用

                06: BeanNameAware#setBeanName 方法的调用

                07: BeanFactoryAware#setBeanFactory 方法的调用

 Init 时期:

    基本的是对配置文件中指定的 init-method 方法进行调用。但在这个时期还可以存在一个回调,即如果该 Bean 实现了 InitializingBean 接口,那么在 init-method 调用前先会调用 InitializingBean#afterPropertiesSet 方法。除此之外,在这个时期可能还会存在一些其它的生命周期,即:如果在 BeanFactory 中注册了 BeanPostProcessor 接口的实例,那么该实例的 postProcessBeforeInitialization 方法将在该时期最先调用,且该实例的 postProcessAfterInitialization 方法将在该时期最后调用。需要注意的是在 Construct 时期所涉及的 InstantiationAwareBeanPostProcessor 接口实现了 BeanPostProcessor 接口。所以如果你在 Construct 时期向 BeanFactory 中注册了一个 InstantiationAwareBeanPostProcessor 实例,那么则可以通过该实例完成 postProcessBeforeInitialization 和 postProcessAfterInitialization 操作。

    这样一来 Init 时期 Bean 的生命周期有4步,为:

                08: BeanPostProcessor#postProcessBeforeInitialization 方法的调用

                09: InitializingBean#afterPropertiesSet 方法的调用

                10: init-method 方法的调用

                11: BeanPostProcessor#postProcessAfterInitialization 方法的调用

    由此可见:在从 BeanFactory 中获取到一个 Bean 实例后,该 Bean 的状态将由 BeanPostProcessor#postProcessAfterInitialization 中的修改决定,如果没有注册BeanPostProcessor 将由 init-method 方法决定。而 setter 的结果并不能保存到最后,但可以为 Init 时期的操作提供基础数据,即 init  时期通过对 inject 时期所注入的值进行计算最后产生所需要的 Bean 的状态。

 Destroy 时期:

    基本的是对配置文件中指定的 destroy-method 方法进行调用。但在这个时期也存在一个回调,即如果该 Bean 实现了 DisposableBean 接口,那么在 destroy-method 调用前会先调用 DisposableBean#destroy 方法。

    这样一来 destroy 时期 Bean 的生命周期有2步,为:

                12: DisposableBean#destroy 方法的调用

                13: init-method 方法的调用

综上:Bean 在 Spring 中的生命周期总共有 13 步,其中有 4 个基本步奏。“扩展”的步奏分为:

  ①: 通过 Bean 实现特定的接口完成的步奏。

          这些步奏涉及 4 个接口,共 4 步。

  ②: 通过向 BeanFactory 中注册特定类的实例完成的步奏。这些步奏可以归类为 before 和 after。即:在 Construct 时期和 Init 时期进行 before 和 after。

          这些步奏涉及 2 个接口,共 5 步。

需要注意的是通过向 BeanFactory 中注册特定实例所完成的步奏对从该 BeanFactory 获取的任何一个 Bean 都是有效的。但除此之外的其它步奏只对特定的 Bean 有效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值