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的销毁方法

     

  • 相关阅读:
    JDK1.8源码(四)——java.util.Arrays类
    JDK1.8源码(三)——java.lang.String类
    Java基础(六)——集合
    设计模式(二)——单例模式
    当你忘了数据库的设计语句,看这一篇就能拾起记忆
    MyBatis之配置优化
    Mybatis中的一些配置,直接拿来就可以用
    网络编程---ip&端口
    java基础数据类型小知识
    学习了MarkDown文本工具
  • 原文地址:https://www.cnblogs.com/figsprite/p/10774930.html
Copyright © 2011-2022 走看看