spring bean的生命周期

  ApplicationContext启动之后会实例化所有的bean定义,这个特性在本书中已经多次提到。但ApplicationContext在实现的过程中依然遵循Spring容器实现流程的两个阶段,只不过它会在启动阶段的活动完成之后,紧接着调用注册到该容器的所有bean定义的实例化方法getBean()。这就是为什么当你得到ApplicationContext类型的容器引用时,容器内所有对
象已经被全部实例化完成。不信你查一下类org.AbstractApplicationContext的refresh()方法。

下图是bean生命周期图

 

第一部分:Bean的声明周期

1. Bean的实例化与BeanWrapper

  容器在内部实现的时候,采用“策略模式(Strategy Pattern)”来决定采用何种方式初始化bean实例。通常,可以通过反射或者CGLIB动态字节码生成来初始化相应的bean实例或者动态生成其子类。org.springframework.beans.factory.support.InstantiationStrategy定义是实例化策略的抽象接口,其直接子类SimpleInstantiationStrategy实现了简单的对象实例化功能,可以通过反射来实例化对象实例,但不支持方法注入方式的对象实例化。CglibSubclassingInstantiation-Strategy继承了SimpleInstantiationStrategy的以反射方式实例化对象的功能,并且通过CGLIB的动态字节码生成功能,该策略实现类可以动态生成某个类的子类,进而满足了方法注入所需的对象实例化需求。默认情况下,容器内部采用的是CglibSubclassingInstantiationStrategy。容器只要根据相应bean定义的BeanDefintion取得实例化信息,结合CglibSubclassingInstantiationStrategy以及不同的bean定义类型,就可以返回实例化完成的对象实例。但是,返回方式上有些“点缀”。不是直接返回构造完成的对象实例,而是以BeanWrapper对构造完成的对象实例进行包裹,返回相应的BeanWrapper实例

    使用BeanWrapper对bean实例操作很方便,可以免去直接使用Java反射API(Java Reflection API)操作对象实例的烦琐。来看一段代码(见代码清单4-49),之后我们就会更加清楚Spring容器内部是如何设置对象属性的了!

2. 各色的Aware接口

3. BeanPostProcessor

BeanPostProcessor的概念容易与BeanFactoryPostProcessor的概念混淆。但只要记住Bean-PostProcessor是存在于对象实例化阶段,而BeanFactoryPostProcessor则是存在于容器启动阶段,这两个概念就比较容易区分了。
与BeanFactoryPostProcessor通常会处理容器内所有符合条件的BeanDefinition类似,Bean-PostProcessor会处理容器内所有符合条件的实例化后的对象实例。该接口声明了两个方法,分别在两个不同的时机执行

通常比较常见的使用BeanPostProcessor的场景,是处理标记接口实现类,或者为当前对象提供
代理实现。在图4-10的第三步中,ApplicationContext对应的那些Aware接口实际上就是通过Bean-
PostProcessor的方式进行处理的

4. InitializingBean和init-method

  实现InitializingBean接口,或者在spring配置文件中bean定义中使用init-method

5. DisposableBean与destroy-method

  实现DisposableBean接口,或者在spring配置文件中bean定义中使用destroy-method

  保证jvm关闭前调用自定义销毁逻辑

  对于ApplicationContext容器来说。道理是一样的。但AbstractApplicationContext为我们提供了registerShutdownHook()方法,该方法底层使用标准的Runtime类的addShutdownHook()方式来调用相应bean对象的销毁逻辑,从而保证在Java虚拟机退出之前,这些singtleton类型的bean对象实例的自定义销毁逻辑会被执行。当然AbstractApplicationContext注册的shutdownHook不只是调用对象实例的自定义销毁逻辑,也包括ApplicationContext相关的事件发布等,代码清单4-58演示了该方法的使用。

第二部分:自定义BeanPostProcessor

(1) 标注需要进行解密的实现类

(2) 实现相应的BeanPostProcessor对符合条件的Bean实例进行处理

  public class PasswordDecodePostProcessor implements BeanPostProcessor

(3) 将自定义的BeanPostProcessor注册到容器

<beans>
<bean id="passwordDecodePostProcessor" class="package.name.PasswordDecodePostProcessor">
<!--如果需要,注入必要的依赖--> </bean> 10
...
 </beans>

大功告成!!!

posted @ 2013-03-05 14:59  beiyeren  阅读(13784)  评论(0编辑  收藏  举报