Spring入门第十一课

IOC容器中Bean的生命周期

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

Spring IOC容器对Bean的生命周期进行管理的过程:

-通过构造器或工厂方法创建Bean实例

-为Bean的属性值和对其他Bean的引用

-调用Bean的初始化方法

-Bean可以使用了

-当容器关闭时,调用Bean的销毁方法

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

下面看代码

package logan.spring.study.cycle;

public class Car {
    
    public Car() {
        // TODO Auto-generated constructor stub
        System.out.println("Car's Constructor...");
    }
    
    private String brand;
    
    public void setBrand(String brand) {
        this.brand = brand;
    }
    
    public void init(){
        System.out.println("init...");
    }
    
    public void destroy(){
        System.out.println("destroy...");
    }

}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="car" class="logan.spring.study.cycle.Car"
        init-method="init"
        destroy-method="destroy">
        <property name="brand" value="Audi"></property>
    </bean>

</beans>

测试代码

package logan.spring.study.cycle;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-cycle.xml");
        
        Car car = (Car) ctx.getBean("car");
        
        System.out.println(car);
        
        ctx.close();

    }

}

输出结果

五月 21, 2017 10:21:56 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7aec35a: startup date [Sun May 21 10:21:56 CST 2017]; root of context hierarchy
五月 21, 2017 10:21:56 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-cycle.xml]
Car's Constructor...
init...
logan.spring.study.cycle.Car@523884b2
五月 21, 2017 10:21:56 上午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@7aec35a: startup date [Sun May 21 10:21:56 CST 2017]; root of context hierarchy
destroy...

创建Bean后置处理器

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

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

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

postProcessAfterInitialization(Object bean,String beanName)

postProcessBeforeinitialization(Object bean, String beanName)

添加Bean后置处理器后Bean的生命周期

Spring IOC容器对Bean的生命周期进行管理的过程:

-通过构造器或者工厂方法创建Bean实例

-为Bean的属性设置值和对其他Bean的引用

-将Bean实例传递给Bean后置处理器的postProcessBeforeInitialization方法

-调用Bean的初始化方法

-将Bean实例传递给Bean后置处理器的postProcessAfterInitialization方法

-Bean可以使用了

-当关不容器时,调用Bean的销毁方法。

看下面代码:

package logan.spring.study.cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcess implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessAfterInitialization" + ", " + bean + ", " + beanName);
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeforeInitialization" + ", " + bean + ", " + beanName);
        return bean;
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="car" class="logan.spring.study.cycle.Car"
        init-method="init"
        destroy-method="destroy">
        <property name="brand" value="Audi"></property>
    </bean>
    
    <bean class="logan.spring.study.cycle.MyBeanPostProcess"></bean>

</beans>

下面是输出结果:

五月 21, 2017 10:44:40 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7aec35a: startup date [Sun May 21 10:44:40 CST 2017]; root of context hierarchy
五月 21, 2017 10:44:40 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-cycle.xml]
Car's Constructor...
postProcessBeforeInitialization, logan.spring.study.cycle.Car@4b9e13df, car
init...
postProcessAfterInitialization, logan.spring.study.cycle.Car@4b9e13df, car
logan.spring.study.cycle.Car@4b9e13df
五月 21, 2017 10:44:41 上午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@7aec35a: startup date [Sun May 21 10:44:40 CST 2017]; root of context hierarchy
destroy...

BeanProcessor很强大,可以偷梁换柱,如下代码:

package logan.spring.study.cycle;

public class Car {
    
    public Car() {
        // TODO Auto-generated constructor stub
        System.out.println("Car's Constructor...");
    }
    
    private String brand;
    
    public void setBrand(String brand) {
        this.brand = brand;
    }
    
    public void init(){
        System.out.println("init...");
    }
    
    public void destroy(){
        System.out.println("destroy...");
    }

    @Override
    public String toString() {
        return "Car [brand=" + brand + "]";
    }
    

}
package logan.spring.study.cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcess implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessAfterInitialization" + ", " + bean + ", " + beanName);
        Car car = new Car();
        car.setBrand("Ford");
        return car;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeforeInitialization" + ", " + bean + ", " + beanName);
        return bean;
    }

}

下面是输出结果:

五月 21, 2017 10:49:29 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7aec35a: startup date [Sun May 21 10:49:29 CST 2017]; root of context hierarchy
五月 21, 2017 10:49:29 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-cycle.xml]
Car's Constructor...
postProcessBeforeInitialization, Car [brand=Audi], car
init...
postProcessAfterInitialization, Car [brand=Audi], car
Car's Constructor...
Car [brand=Ford]
五月 21, 2017 10:49:29 上午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@7aec35a: startup date [Sun May 21 10:49:29 CST 2017]; root of context hierarchy
destroy...
原文地址:https://www.cnblogs.com/LoganChen/p/6884190.html