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...