前言:Spring可以管理singleton作用域的Bean的生命周期,Spring可以精确知道该Bean何时被创建、何时被初始化完成、容器何时准备销毁该Bean实例。Spring管理Bean的生命周期行为主要有两个时机,一是注入依赖关系之后,二是即将销毁Bean之前。(本篇主要针对ApplicationContext容器进行展开)
本篇文章重点关注以下问题:
- 引言;
- Spring容器中各级别的生命周期接口及方法;
- 演示Spring Bean的生命周期。
0. 引言
对于prototype作用域的Bean,Spring容器仅仅负责创建,当容器创建了Bena实例之后,Bean实例完全交给客户端代码管理,容器不再跟踪其生命周期。每次客户端请求prototype作用域的Bean时,Spring都会产生一个新的实例,Spring容器无法知道它曾经创造了多少个prototype作用域的Bean,也无从知道这些prototype作用域的Bean什么时候才会销毁。因此,Spring无法管理prototype作用域的Bean。 对于singleton作用域的Bean,每次客户端代码请求时,都返回同一个贡献实例,客户端代码不能控制Bean的销毁,Spring容器负责跟踪Bean实例的产生、销毁。Spring容器可以在创建Bean之后,进行某些通用资源的申请;还可以在销毁Bean实例之前,先回收某些资源,比如数据库连接等。 首先给出Spring Bean的完整生命周期,从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点:1. Spring容器中各级别的生命周期接口及方法
我们将Spring容器中Bean的生命周期级别分为四级,分别是:Bean自身方法、Bean级生命周期接口方法、容器级生命周期接口方法、工厂后处理器接口方法。
1. Bean自身的方法,包括: * Bean本身调用的方法 * 通过配置文件中的init-method和destroy-method指定的方法; 2. Bean级生命周期接口方法,包括: * InitializingBean接口 * DiposableBean接口 * BeanNameAware接口 * ApplicationContextAware接口 * BeanFactoryAware接口 * 其他 3. 容器级生命周期接口方法,包括: * InstantiationAwareBeanPostProcessor接口实现 * BeanPostProcessor 接口实现 * 一般称它们的实现类为“后处理器” 4. 工厂级生命周期口方法(BeanFactoryPostProcessor接口的实现类) * AspectJWeavingEnabler * ConfigurationClassPostProcessor * CustomAutowireConfigurer等 * 工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
2. Bean自身方法及Bean级生命周期方法
Bean自身的方法:调用构造函数实例化bean,调用setter设置属性,调用init-method,destroy-method。
1. init-method :指定某个方法在Bean实例化完成,依赖关系设置结束后执行; 2. destroy-method :指定某个方法在Bean销毁之前被执行。Bean级生命周期方法:如BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean,这些接口由bean直接实现。
1. InitializingBean接口 :指定某个方法在Bean实例化完成,依赖关系设置结束后执行;(init-method之前执行) 2. DiposableBean接口 :指定某个方法在Bean销毁之前被执行。(destory-method之前执行) 3. ApplicationContextAware接口 :在实例化Bean时,为Bean注入ApplicationContext 4. BeanNameAware接口 :在实例化Bean时,为Bean注入beanName下面的Person类中定义了Bean自身方法以及Bean级生命周期方法,便于最后进行测试,以观察Person实例的整个生命周期变化。
package com.wj.chapter5.life.all; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * * Bean自身方法 * * Bean本身调用的方法 * * init-method * * destroy-method * * Bean级生命周期接口: * * BeanNameAware : 在实例化Bean时,为Bean注入beanName * * ApplicationContextAware : 在实例化Bean时,为Bean注入ApplicationContext * * InitializingBean : 在实例化Bean之前,进行初始化操作 * * DisposableBean : 在销毁Bean之前,进行析构操作 * @author Administrator * */ public class Person implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean { private String name; private String address; private int phone; private ApplicationContext applicationContext; private String beanName; public Person() { System.out.println("【Person】【构造器】"); } /*********************************** Bean自身方法begin. ************************************/ // 通过<bean>的init-method属性指定的初始化方法 public void myInit() { System.out.println("【Bean自身方法】【init-method】初始化方法..."); } // 通过<bean>的destroy-method属性指定的初始化方法 public void myDestory() { System.out.println("【Bean自身方法】【destroy-method】销毁方法..."); } public void sayHello() { System.out.println("【Bean自身方法】sayHello..."); } /*********************************** Bean级生命接口方法begin. ************************************/ public void setName(String name) { this.name = name; System.out.println("【Bean级接口】【注入属性】注入属性name..."); } public void setAddress(String address) { this.address = address; System.out.println("【Bean级接口】【注入属性】注入属性address..."); } public void setPhone(int phone) { this.phone = phone; System.out.println("【Bean级接口】【注入属性】注入属性phone..."); } // 这是BeanFactoryAware接口方法 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; System.out.println("【Bean级接口】【ApplicationContextAware接口】注入Spring容器ApplicationContext..."); } // 这是BeanNameAware接口方法 @Override public void setBeanName(String beanName) { this.beanName = beanName; System.out.println("【Bean级接口】【BeanNameAware接口】注入beanName..."); } // 这是InitializingBean接口方法 @Override public void afterPropertiesSet() throws Exception { System.out.println("【Bean级接口】【InitializingBean接口】初始化方法..."); } // 这是DiposibleBean接口方法 @Override public void destroy() throws Exception { System.out.println("【DiposibleBean接口】销毁方法..."); } @Override public String toString() { return "Person [name=" + name + ", address=" + address + ", phone=" + phone + ", applicationContext=" + applicationContext + ", beanName=" + beanName + "]"; } }
3. 容器级生命周期接口方法
容器级生命周期接口方法:有InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口实现,一般称他们的实现类为后处理器。实现类独立于bean,以容器附加装置的形式注册到spring当中。当spring创建任何bean时,这些后处理器都会发生作用,所以后处理器的影响是全局性的。当然,用户可以通过合理的编写后处理器,让其仅对感兴趣的bean进行加工处理。
Bean级生命接口和容器级生命接口是个性和共性辩证统一思想的体现。前者解决bean的个性化处理的问题,后者解决容器中某些bean共性化处理的问题。
1. InstantiationAwareBeanPostProcessor接口:此接口可以在Bean实例化前、Bean实例化后分别进行操作,也可以对Bean实例化之后进行属性操作;(为BeanPostProcessor的子接口) 2. BeanPostProcessor接口:此接口的方法可以对Bean的属性进行更改。
下面分别实现两种容器级接口,首先是InstantiationAwareBeanPostProcessor接口:
package com.wj.chapter5.life.all; import java.beans.PropertyDescriptor; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; /** * 容器级生命周期接口: * InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口, * 一般我们继承Spring为其提供的适配器类,InstantiationAwareBeanPostProcessorAdapter来使用它, * 此接口可以在Bean实例化前、Bean实例化后分别进行操作,也可以对Bean实例化之后进行属性操作 */ public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor() { super(); System.out.println("【容器级接口】【InstantiationAwareBeanPostProcessor实现类】【构造器】"); } // 实例化Bean之前调用 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("【容器级接口】【InstantiationAwareBeanPostProcessor实现类】实例化Bean之前调用"); return null; } // 实例化Bean之后调用 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("【容器级接口】【InstantiationAwareBeanPostProcessor实现类】实例化Bean之后调用"); return true; } // 初始化Bean之前调用 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("【容器级接口】【InstantiationAwareBeanPostProcessor实现类】初始化Bean之前调用"); return bean; } // 初始化Bean之后调用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("【容器级接口】【InstantiationAwareBeanPostProcessor实现类】初始化Bean之后调用"); return bean; } // 设置某个属性时调用 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("【容器级接口】【InstantiationAwareBeanPostProcessor实现类】实例化Bean之后,设置某个属性时调用"); return pvs; } }然后实现BeanPostProcessor接口:
package com.wj.chapter5.life.all; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * 容器级生命周期接口: * 此接口的方法可以对Bean的属性进行更改 */ public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { System.out.println("【容器级接口】【MyBeanPostProcessor实现类】【构造器】"); } // 初始化Bean之前调用 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("【容器级接口】【BeanPostProcessor实现类】初始化Bean之前调用"); return bean; } // 初始化Bean之后调用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("【容器级接口】【BeanPostProcessor实现类】初始化Bean之后调用"); return bean; } }注意:InstantiationAwareBeanPostProcessor接口实际上是BeanPostProcessor的子接口,所以实际开发中用InstantiationAwareBeanPostProcessor接口的适配器类InstantiationAwareBeanPostProcessorAdapter即可。 4. 工厂级生命周期方法