zoukankan      html  css  js  c++  java
  • 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的销毁方法

     

  • 相关阅读:
    [Luogu P3626] [APIO2009] 会议中心
    杭电 1869 六度分离 (求每两个节点间的距离)
    杭电 1874 畅通工程续 (求某节点到某节点的最短路径)
    最短路径模板
    杭电 2544 最短路径
    POJ 1287 Networking (最小生成树模板题)
    NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
    POJ 2485 Highways (求最小生成树中最大的边)
    杭电 1233 还是畅通工程 (最小生成树)
    杭电 1863 畅通工程 (最小生成树)
  • 原文地址:https://www.cnblogs.com/figsprite/p/10774930.html
Copyright © 2011-2022 走看看