IOC容器中Bean的生命周期

SpringIOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务。

我们先来看看Bean的生命周期:

  • 通过构造器或工厂创建Bean实例
  • 为Bean的属性设置值和其他Bean的引用,
  • 调用Bean的初始化方法
  • Bean可以使用了
  • 当容器关闭时,调用Bean的销毁方法

在Bean的声明里设置init-method和destroy-method属性,为Bean指定初始化和销毁方法。

先做一个小测试

  1. package com.figsprite.bean.cycle;  
  2.     
  3. public class Car {  
  4.     public Car(){  
  5.         System.out.println("Car的构造函数");  
  6.     }  
  7.     
  8.     public String brand;  
  9.     
  10.     public void setBrand(String brand) {  
  11.         System.out.println("setBrand...");  
  12.         this.brand = brand;  
  13.     }  
  14.         
  15.     public void init(){  
  16.         System.out.println("init...");  
  17.     }  
  18.         
  19.     public void destroy(){  
  20.         System.out.println("destroy...");  
  21.     }  
  22. }  

在配置文件中我们可以使用<bean>中的 init-method 和destroy-method属性指定该Bean的初始化方法和销毁方法。

  1. <bean id="car" class="com.figsprite.bean.cycle.Car"  
  2. init-method="init" destroy-method="destroy">  
  3.     <property name="brand" value="奔驰"/>  
  4. </bean>  

我们创建一个测试类,就通过IOC容器创建一个Bean对象

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-cycle.xml");
Car car = (Car) ctx.getBean("car");
ctx.close();

看看输出内容:

创建Bean后置处理器

    Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理。

    Bean的后置处理器对IOC容器里的所有Bean实例逐一处理,而非单一实例,其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性。

    对Bean后置处理器而言,需要实现Interface BeanPostProcessor接口,在初始化方法被调用前后,Spring将把每一个Bean实例分别床底给上述接口的以下两个方法:

    打开源码,发现这个接口就只有两个方法:一个用于Bean初始化之前,一个用于Bean初始化之后:

    

    加上这Bean的后置处理,Bean的生命周期就会变得更加细致,我们新写一个新的类,这里的返回值我没做处理,大家可以根据具体需要,将Bean定制,将修改的Bean返回,

  1. package com.figsprite.bean.cycle;  
  2.     
  3. import org.springframework.beans.BeansException;  
  4. import org.springframework.beans.factory.config.BeanPostProcessor;  
  5.     
  6. public class MyBeanPostProcessor implements BeanPostProcessor {  
  7.     @Override  
  8.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
  9.         System.out.println("postProcessBeforeInitialization"+bean+","+beanName);  
  10.         return bean;  
  11.     }  
  12.     
  13.     @Override  
  14.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
  15.         System.out.println("postProcessAfterInitialization"+bean+","+beanName);  
  16.         return bean;  
  17.     }  
  18. }  

回到配置文件,配置bean的后置处理器,不需要配置id,IOC容器自动识别是一个BeanPostProcessor:

<!--配置bean的后置处理器-->
<bean class="com.figsprite.bean.cycle.MyBeanPostProcessor"/>

顺道在测试类里加一句打印car的方法,观察结果:

 

接下来我们在Car.java里面写一个toString方法,看看输出

一切都很正常,然后我们就可以在刚刚写的两个方法里"偷梁换柱"了:

  1. package com.figsprite.bean.cycle;  
  2.     
  3. import org.springframework.beans.BeansException;  
  4. import org.springframework.beans.factory.config.BeanPostProcessor;  
  5.     
  6. public class MyBeanPostProcessor implements BeanPostProcessor {  
  7.     
  8.     @Override  
  9.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
  10.         System.out.println("postProcessAfterInitialization"+bean+","+beanName);  
  11.     
  12.         return bean;  
  13.     }  
  14.         
  15.     @Override  
  16.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
  17.         System.out.println("postProcessBeforeInitialization"+bean+","+beanName);  
  18.         Car car = new Car();  
  19.         car.setBrand("宝马");  
  20.         return car;  
  21.     }  
  22. }  

我们在 postProcessAfterInitialization里将返回值做修改看看输出:

如我们所愿,不过两个方法是处理所有当前所在的配置文件中的bean的,所以一般在处理之前要判断bean的类型,作出相应动作

  1. @Override  
  2. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
  3.     System.out.println("postProcessAfterInitialization"+bean+","+beanName);  
  4.     if("car".equals(beanName)){  
  5.         //......  
  6.     }  
  7.     return bean;  
  8. }  

这样我们就可以丰富Bean的生命周期:

  • 通过构造器或工厂创建Bean实例
  • 为Bean的属性设置值和其他Bean的引用
  • 将Bean实例传给Bean后置处理器的postProcessBeforeInitialization方法
  • 调用Bean的初始化方法
  • 将Bean实例传给Bean后置处理器的postProcessAfterInitialization方法
  • Bean可以使用了
  • 当容器关闭时,调用Bean的销毁方法

 

猜你喜欢

转载自www.cnblogs.com/figsprite/p/10774930.html