ApplicationContext中Bean的生命周期

来源:互联网 发布:淘宝助理批量上传图片 编辑:程序博客网 时间:2024/05/16 11:59

Bean在应用上下文中的生命周期和在BeanFactory中生命周期类似,不同是,如果Bean实现了org.springframework.context.ApplicationContextAware接口,会增加一个调用该接口方法setApplicationContext()的步骤,如3-12所示:

 图3-12  ApplicationContext中Bean的生命周期

此外,如果配置文件中声明了工厂后处理器接口BeanFactoryPostProcessor的实现类,则应用上下文在装载配置文件之后初始化Bean实例之前将调用这些BeanFactoryPost Processor对配置信息进行加工处理。Spring框架提供了多个工厂后处理器:

CustomEditorConfigurer、PopertyPlaceholderConfigurer等,我们将在第5章中详细介绍它们的功用。如果配置文件中定义了多个工厂后处理器,最好让它们实现org.springframework.core.Ordered接口,以便Spring以确定的顺序调用它们。工厂后处理器是容器级的,仅在应用上下文初始化时调用一次,其目的是完成一些配置文件的加工处理工作。

ApplicationContext和BeanFactory另一个最大的不同之处在于:前者会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而后者需要在代码中通过手工调用addBeanPostProcessor()方法进行注册。这也是为什么在应用开发时,我们普遍使用ApplicationContext而很少使用BeanFactory的原因之一。

在ApplicationContext中,我们只需要在配置文件中通过<bean>定义工厂后处理器和Bean后处理器,它们就会按预期的方式运行。

来看一个使用工厂后处理器的实例,假设我们希望对配置文件中car的brand配置属性进行调整,则可以编写一个如下的工厂后处理器:

代码清单3-31  工厂后处理器:MyBeanFactoryPostProcessor.java

    package com.baobaotao.context;      import org.springframework.beans.BeansException;      import org.springframework.beans.factory.config.BeanDefinition;      import org.springframework.beans.factory.config.BeanFactoryPost Processor;      import org.springframework.beans.factory.config.ConfigurableListable BeanFactory;      import com.baobaotao.Car;           public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{        //①对car <bean>的brand属性配置信息进行“偷梁换柱”的加工操作        public void postProcessBeanFactory(ConfigurableListableBeanFactory bf)        throws BeansException {              BeanDefinition bd = bf.getBeanDefinition("car");                    bd.getPropertyValues().addPropertyValue("brand", "奇瑞QQ");              System.out.println("调用BeanFactoryPostProcessor.postProcessBean Factory()!");          }      }  

ApplicationContext在启动时,将首先为配置文件中每个<bean>生成一个BeanDefinition对象,BeanDefinition是<bean>在Spring容器中的内部表示。当配置文件中所有的<bean>都被解析成BeanDefinition时,ApplicationContext将调用工厂后处理器的方法,因此我们有机会通过程序的方式调整Bean的配置信息。在这里,我们将car对应的BeanDefinition进行调整,将brand属性设置为"奇瑞QQ",下面是具体的配置:

代码清单3-32  beans.xml

    <!--①这个brand属性的值将被工厂后处理器更改掉-->      <bean id="car" class="com.baobaotao.Car" init-method="myInit" destroy-method="myDestory"            p:brand="红旗CA72"            p:maxSpeed="200"/>      <!--②工厂后处理器-->      <bean id="myBeanPostProcessor"              class="com.baobaotao.context.MyBeanPostProcessor"/>      <!--③注册Bean后处理器-->      <bean id="myBeanFactoryPostProcessor"              class="com.baobaotao.context.MyBeanFactoryPostProcessor"/> 

②和③处定义的BeanPostProcessor和BeanFactoryPostProcessor会自动被ApplicationContext识别并注册到容器中。②处注册的工厂后处理器将会对①处配置的属性值进行调整。在③处,我们还声明了一个Bean后处理器,它也可以对Bean的属性进行调整。启动容器并查看car Bean的信息,我们将发现car Bean的brand属性成功被工厂后处理器更改了。

Spring为Bean提供了细致周全的生命周期过程,通过实现特定的接口或通过<bean>属性设置,都可以对Bean的生命周期过程施加影响,Bean的生命周期不但和其实现的接口相关,还与Bean的作用范围有关。为了让Bean绑定在Spring框架上,我们推荐使用配置方式而非接口方式进行Bean生命周期的控制。