Spring bean生命周期

Spring IOC 容器可以管理 Bean 的生命周期,Spring 允许在 Bean 生命周期的特定点执行定制的任务.
•Spring IOC 容器对 Bean的生命周期进行管理的过程:
–通过构造器或工厂方法创建 Bean实例
–为 Bean 的属性设置值和对其他Bean的引用
调用 Bean的初始化方法
–Bean 可以使用了
当容器关闭时,调用 Bean的销毁方法

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

package com.xiya.spring.beans.cycle;

/**
 * Created by N3verL4nd on 2017/3/20.
 */
public class Car {
    private String brand;
    private int price;

    public Car() {
        System.out.println("Car's constructor...");
    }

    public Car(String brand, int price) {
        this.brand = brand;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
        System.out.println("setBrand...");
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
        System.out.println("setPrice...");
    }

    public void init() {
        System.out.println("init...");
    }

    public void destroy() {
        System.out.println("destroy...");
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
<?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="com.xiya.spring.beans.cycle.Car" init-method="init" destroy-method="destroy">
        <property name="brand" value="BMW"/>
        <property name="price" value="1000000"/>
    </bean>
</beans>
package com.xiya.spring.beans.cycle;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by N3verL4nd on 2017/3/20.
 */
public class Main {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans-cycle.xml");
        Car car = (Car) context.getBean("car");
        System.out.println(car);
        context.close();
    }
}

输出:

三月 20, 2017 3:36:06 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1d56ce6a: startup date [Mon Mar 20 15:36:06 CST 2017]; root of context hierarchy
三月 20, 2017 3:36:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-cycle.xml]
Car's constructor...
setBrand...
setPrice...
init...
Car{brand='BMW', price=1000000}

三月 20, 2017 3:36:06 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1d56ce6a: startup date [Mon Mar 20 15:36:06 CST 2017]; root of context hierarchy
destroy...


•Bean 后置处理器允许在调用初始化方法前后对Bean 进行额外的处理.
Bean 后置处理器对IOC 容器里的所有Bean 实例逐一处理,而非单一实例.其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性.
•对Bean 后置处理器而言,需要实现BeanPostProcessor接口. 在初始化方法被调用前后,Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法:
public interface BeanPostProcessor {

   /**
    * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
    * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
    * or a custom init-method). The bean will already be populated with property values.
    * The returned bean instance may be a wrapper around the original.
    * @param bean the new bean instance
    * @param beanName the name of the bean
    * @return the bean instance to use, either the original or a wrapped one;
    * if {@code null}, no subsequent BeanPostProcessors will be invoked
    * @throws org.springframework.beans.BeansException in case of errors
    * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
    */
   Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

   /**
    * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
    * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
    * or a custom init-method). The bean will already be populated with property values.
    * The returned bean instance may be a wrapper around the original.
    * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
    * instance and the objects created by the FactoryBean (as of Spring 2.0). The
    * post-processor can decide whether to apply to either the FactoryBean or created
    * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
    * <p>This callback will also be invoked after a short-circuiting triggered by a
    * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
    * in contrast to all other BeanPostProcessor callbacks.
    * @param bean the new bean instance
    * @param beanName the name of the bean
    * @return the bean instance to use, either the original or a wrapped one;
    * if {@code null}, no subsequent BeanPostProcessors will be invoked
    * @throws org.springframework.beans.BeansException in case of errors
    * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
    * @see org.springframework.beans.factory.FactoryBean
    */
   Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

测试:

package com.xiya.spring.beans.cycle;

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

/**
 * Created by N3verL4nd on 2017/3/20.
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization..." + bean + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization..." + bean + beanName);
        Car car = (Car) bean;
        car.setBrand("audi");
        return car;
    }
}
 

输出:

三月 20, 2017 3:55:34 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1d56ce6a: startup date [Mon Mar 20 15:55:34 CST 2017]; root of context hierarchy
三月 20, 2017 3:55:34 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-cycle.xml]
Car's constructor...
setBrand...
setPrice...
postProcessBeforeInitialization...Car{brand='BMW', price=1000000}car
init...
postProcessAfterInitialization...Car{brand='BMW', price=1000000}car
setBrand...

三月 20, 2017 3:55:34 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1d56ce6a: startup date [Mon Mar 20 15:55:34 CST 2017]; root of context hierarchy
Car{brand='audi', price=1000000}
destroy...


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

•Spring IOC 容器对 Bean的生命周期进行管理的过程:
–通过构造器或工厂方法创建 Bean实例
–为 Bean 的属性设置值和对其他Bean的引用
Bean实例传递给 Bean后置处理器的 postProcessBeforeInitialization方法
–调用 Bean 的初始化方法
Bean实例传递给 Bean后置处理器的 postProcessAfterInitialization方法
–Bean 可以使用了
–当容器关闭时, 调用Bean的销毁方法

posted @ 2017-03-20 15:56  N3verL4nd  阅读(227)  评论(0编辑  收藏  举报