首页 > 代码库 > Bean的生命周期

Bean的生命周期

-------------siwuxie095

   

   

   

   

   

   

   

   

Spring 容器中的 Bean 拥有明确的生命周期,由多个特定的生命阶段

组成,每个生命阶段都开出了一扇门,允许外界对 Bean 施加控制

   

Spring 中,可以从 Bean 的作用范围和实例化 Bean 时所经历的一系列

阶段(两个方面)来描述 Bean 的生命周期:

   

· BeanFactory Bean 的生命周期

   

· ApplicationContext Bean 的生命周期

   

   

   

   

   

   

BeanFactory Bean 的生命周期

   

   

如下,通过图形化的方式描述 BeanFactory Bean 的生命周期:

   

技术分享

   

   

1)当调用者通过 getBean() 向容器请求某一个 Bean 时,如果容器

注册了 InstantiationAwareBeanPostProcessor 接口,在实例化 Bean

之前,将调用该接口的 postProcessBeforeInstantiation() 方法

   

   

2)根据配置情况调用 Bean 构造函数 工厂方法实例化 Bean

   

   

3)如果容器注册了 InstantiationAwareBeanPostProcessor 接口,

在实例化 Bean 之后,调用该接口的 postProcessAfterInstantiation()

方法,可在这里对已经实例化的对象进行一些 "梳妆打扮"

   

   

4)如果 Bean 配置了属性信息,容器在这一步着手将配置值设置到 Bean 对应的

属性中,不过在设置每个属性之前将先调用 InstantiationAwareBeanPostProcessor

接口的 postProcessPropertyValues() 方法

   

   

5)调用 Bean 的属性设置方法设置属性值

   

   

6)如果 Bean 实现了 BeanNameAware 接口,将调用 setBeanName() 接口方法,

将配置文件中该 Bean 对应的名称设置到 Bean

   

   

7)如果 Bean 实现了 BeanFactoryAware 接口,将调用 setBeanFactory() 接口方法,

BeanFactory 容器实例设置到 Bean

   

   

8)如果 BeanFactory 装配了 BeanPostProcessor 后处理器,将调用

BeanPostProcessor Object postProcessBeforeInitialization() 接口

方法对 Bean 进行加工操作

   

其入参 bean 是当前正在处理的 Bean,而 beanName 是当前 Bean

配置名,返回的对象为加工处理后的 Bean

   

用户可以使用该方法对某些 Bean 进行特殊的处理,甚至改变 Bean 的行为,

BeanPostProcessor Spring 框架中占有重要的地位,为容器提供对 Bean

进行后续加工处理的切入点

   

Spring 容器所提供的各种 "神奇功能"(如:AOP、动态代理等)都通过

BeanPostProcessor 实施

   

   

9)如果 Bean 实现了 InitializingBean 的接口,将调用接口的

afterPropertiesSet() 方法

   

   

10)如果在 <bean> 中通过 init-method 属性定义了初始化方法,

将执行这个方法

   

<bean> 配置文件中的 Bean 节点」

   

   

11)BeanPostProcessor 后处理器定义了两个方法:

   

1)Object postProcessBeforeInitialization() 方法在第(8)步调用

   

2Object postProcessAfterInitialization() 方法在此时调用,容器再

次获得对 Bean 进行加工处理的机会

   

   

12)如果在 <bean> 中指定 Bean 的作用范围为 scope="prototype",

Bean 返回给调用者,调用者负责 Bean 后续生命的管理,Spring 不再

管理这个 Bean 的生命周期

   

如果作用范围设置为 scope="singleton",则将 Bean 放入到 Spring IoC

容器的缓存池中,并将 Bean 引用返回给调用者,Spring 继续对这些 Bean

进行后续的生命管理

   

   

13)对于 scope="singleton" Bean,当容器关闭时,将触发 Spring

Bean 的后续生命周期的管理工作,首先如果 Bean 实现了 DisposableBean

接口,则将调用接口的 afterPropertiesSet() 方法,可以在此编写释放资源、

记录日志等操作

   

   

14)对于 scope="singleton" Bean,如果通过 <bean>

destroy-method 属性指定了 Bean 的销毁方法,Spring 将执行

Bean 的这个方法,完成 Bean 资源的释放等操作

   

   

   

   

Bean 的完整生命周期从 Spring 容器着手实例化 Bean 开始,直到最终

销毁 Bean,这当中经过了许多关键点,每个关键点都涉及特定的方法调

用,可以将这些方法大致划分为三类:

   

1)Bean 自身的方法

   

如:调用 Bean 构造函数实例化 Bean,调用 Setter 设置 Bean 的属性值

以及通过 <bean> init-method destroy-method 所指定的方法

   

   

2)Bean 级生命周期接口方法

   

如:BeanNameAware、BeanFactoryAware、InitializingBean 和

DisposableBean,这些接口方法由 Bean 类直接实现

   

   

3)容器级生命周期接口方法:

   

在上图中绿色的步骤是由 InstantiationAwareBeanPostProcessor

BeanPostProcessor 两个接口实现,一般称其实现类为 "后处理器"

   

后处理器接口一般不由 Bean 本身实现,它们独立于 Bean,实现类以

容器附加装置的形式注册到 Spring 容器中并通过接口反射为 Spring

容器预先识别

   

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

所以这些后处理器的影响是全局性的。当然,用户可以通过合理地编

写后处理器,让其仅对感兴趣的 Bean 进行加工处理

   

   

   

Bean 级生命周期接口 容器级生命周期接口 是个性和共性辩证统一思想

的体现,前者解决 Bean 个性化处理的问题;而后者解决容器中某些 Bean

共性化处理的问题

   

   

Spring 容器中可以注册多个后处理器。只要它们同时实现 org.springframe

work.core.Ordered 接口,容器将按特定的顺序依次调用这些后处理器。所

以在上图绿色的步骤中都可能调用多个后处理器进行一系列的加工操作

   

InstantiationAwareBeanPostProcessor 其实是 BeanPostProcessor 接口的

子接口,在 Spring 1.2 中定义,在 Spring 2.0 中为其提供了一个适配器类

   

InstantiationAwareBeanPostProcessorAdapter,一般情况下,可以方便地

扩展该适配器覆盖感兴趣的方法以定义实现类

   

   

   

   

   

ApplicationContext Bean 的生命周期

   

   

如下,通过图形化的方式描述 ApplicationContext 中 Bean 的生命周期:

   

技术分享

   

   

Bean ApplicationContext 中的生命周期和在 BeanFactory 中生命周期

类似,不同是,如果 Bean 实现了 ApplicationContextAware 接口,会增

加一个调用该接口的方法 setApplicationContext() 步骤

   

此外,如果配置文件中声明了工厂后处理器接口 BeanFactoryPostProcessor

的实现类,则应用上下文在装载配置文件之后,初始化 Bean 实例之前将调用

这些 BeanFactoryPostProcessor 对配置信息进行加工处理

   

   

   

ApplicationContext BeanFactory 另一个不同之处在于:

   

前者会利用 Java 反射机制自动识别出配置文件中定义的 BeanPostProcessor,

InstantiationAwareBeanPostProcessor BeanFactoryPostProcessor,并

自动将它们注册到应用上下文中

   

而后者需要在代码中通过手工调用 addBeanPostProcessor() 方法进行注册

   

   

这也是为什么在应用开发时,我们普遍使用 ApplicationContext 而很少使用

BeanFactory 的原因之一

   

ApplicationContext 中,只需要在配置文件中通过 <bean> 定义工厂

后处理器和 Bean 后处理器,它们就会按预期的方式执行

   

   

   

   

   

   

   

【made by siwuxie095】

Bean的生命周期