spring BeanFactory及ApplicationContext中Bean的生命周期
spring bean 的生命周期
spring BeanFactory及ApplicationContext在读取配置文件后、实例化bean前后、设置bean的属性前后这些点都可以通过实现接口添加我们自己的逻辑
spring BeanFactory中Bean的生命周期
demo1
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.16.RELEASE</version> </dependency> </dependencies>
import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; /** * BeanFactoryAware 觉察到 * InitializingBean 初始化 * Disposable 一次性的,可任意处理的; 用后就抛弃的 * * BeanFactoryAware、BeanNameAware、InitializingBean、DisposableBean都是Bean级的生命周期控制接口 */ public class Car implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { // 品牌 private String brand; // 颜色 private String color; // 最快速度 private int maxSpeed; public Car() { System.out.println("构造方法执行"); } public void setBrand(String brand) { System.out.println("setBrand方法执行"); this.brand = brand; } public String getColor() { return this.color; } public void setColor(String color) { this.color = color; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } public void introduce() { System.out.println("brand:" + brand + ";color:" + color + ";maxSpeed:" + maxSpeed); } private BeanFactory beanFactory; @Override // 实现BeanFactoryAware需要重写的唯一方法 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("调用BeanFactoryAware接口定义的setBeanFactory方法"); this.beanFactory = beanFactory; } private String beanName; @Override // 实现BeanNameAware需要重写的唯一方法 public void setBeanName(String beanName) { System.out.println("调用BeanNameAware接口定义的setBeanName方法"); this.beanName = beanName; } @Override // 实现InitializingBean需要重写的唯一方法 public void afterPropertiesSet() throws Exception { System.out.println("调用InitializingBean接口定义的afterPropertiesSet方法"); } @Override // 实现DisposableBean需要重写的唯一方法 public void destroy() throws Exception { System.out.println("调用DisposableBean接口定义的destroy方法"); } // 通过<bean>的init-method属性指定的初始化方法 public void myInit() { System.out.println("调用init-method指定的myInit方法,将maxSpeed设置为240"); this.maxSpeed = 240; } // 通过<bean>的destroy-method属性指定的销毁方法 public void myDestroy() { System.out.println("调用destroy-method指定的myDestroy方法"); } }
import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import java.beans.PropertyDescriptor; public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { /** * 在实例化Bean前调用,仅对容器中的car Bean处理 * * 父类实现了接口 SmartInstantiationAwareBeanPostProcessor, * SmartInstantiationAwareBeanPostProcessor 又继承了接口 InstantiationAwareBeanPostProcessor * InstantiationAwareBeanPostProcessor 又继承了 BeanPostProcessor * 有方法postProcessBeforeInstantiation */ public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法执行"); } return null; } /** * 在实例化Bean后调用,仅对容器中的car Bean处理 * * 同上,InstantiationAwareBeanPostProcessor 有方法 postProcessAfterInstantiation */ public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor 接口的 postProcessAfterInstantiation 方法执行"); } return true; } /** * 在设置某个属性时调用,仅对car Bean的品牌属性值进行处理,还可以通过pds入参进行过滤 * * 同上,InstantiationAwareBeanPostProcessor 有方法 postProcessPropertyValues */ public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues 方法执行"); } return pvs; } }
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * processor 加工,处理 * BeanPostProcessor后处理器在spring框架中占有重要的地位,这是容器对Bean进行后续加工处理的切入点; * spring提供的动态代理、AOP都是通过BeanPostProcessor实现的 */ public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("car")) { Car car = (Car)bean; if (car.getColor() == null) { System.out.println("调用接口BeanPostProcessor的postProcessBeforeInitialization方法," + "color为空,设置为默认黑色"); car.setColor("黑色"); } } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("car")) { Car car = (Car)bean; if (car.getMaxSpeed() >= 200) { System.out.println("调用接口BeanPostProcessor的postProcessAfterInitialization方法," + "将maxSpeed调整为200"); car.setMaxSpeed(200); } } return bean; } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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="Car" init-method="myInit" destroy-method="myDestroy" p:brand="宝马373" p:maxSpeed="220"/> </beans>
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; /** * 测试类 */ public class BeanLifeCycle { public static void main(String[] args) { lifeCycleBeanFactory(); } private static void lifeCycleBeanFactory() { // 装载配置文件 ClassPathResource resource = new ClassPathResource("my.xml"); // 启动容器 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) beanFactory); reader.loadBeanDefinitions(resource); // 向容器中注册MyBeanPostProcessor后处理器 ((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyBeanPostProcessor()); // 向容器中注册MyInstantiationAwareBeanPostProcessor后处理器 ((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor()); // 第一次从容器中获取car,将触发容器实例化这个Bean,这将引发Bean生命周期方法的调用 Car car1 = (Car)beanFactory.getBean("car"); car1.introduce(); car1.setColor("红色"); // 第二次从容器中获取car,直接从缓存池中获取 Car car2 = (Car) beanFactory.getBean("car"); // 查看car1和car2是否指向同一引用 System.out.println("car1==car2:" + (car1 == car2)); ((DefaultListableBeanFactory)beanFactory).destroySingletons(); } }
1、InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法执行 构造方法执行 2、InstantiationAwareBeanPostProcessor 接口的 postProcessAfterInstantiation 方法执行 3、InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues 方法执行 setBrand方法执行 4、调用BeanNameAware接口定义的setBeanName方法 5、调用BeanFactoryAware接口定义的setBeanFactory方法 6、调用接口BeanPostProcessor的postProcessBeforeInitialization方法,color为空,设置为默认黑色 7、调用InitializingBean接口定义的afterPropertiesSet方法 8、调用init-method指定的myInit方法,将maxSpeed设置为240 9、调用接口BeanPostProcessor的postProcessAfterInitialization方法,将maxSpeed调整为200 brand:宝马373;color:黑色;maxSpeed:200 car1==car2:true 10、调用DisposableBean接口定义的destroy方法 11、调用destroy-method指定的myDestroy方法 输出分析: 在一个bean实例化之间之后,调用1、2。 1的方法入参是Class<?> beanClass, String beanName,分别对应bean的class和id 2的方法入参是Object bean, String beanName,分别对应实例化好的bean和bean的id 在属性填充前,调用3。 3的方法入参是PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName pvs里封装着属性值,pds里封装着属性名,bean是实例化后的bean,beanName是bean的id 属性填充后,调用4、5。 4的方法入参是String beanName,可以把beanName也就是bean的id缓存起来,保存为一个成员变量 5的方法入参是BeanFactory beanFactory,可以把beanFactory缓存起来,保存为一个成员变量 在bean初始化之前之后调用6、9,这是BeanPostProcessor的方法,可以修改属性值,可以添加AOP 7、8是初始化方法 10、11是销毁方法
其中的BeanPostProcessor接口非常重要,spring的动态代理、AOP都是通过实现这个接口而为bean添加行为的
spring ApplicationContext中Bean的生命周期
Spring Bean在ApplicationContext和BeanFactory中的生命周期类似。
不同的是,如果Bean实现了org.springframework.context.ApplicationContextAware接口,会增加一个调用该接口方法setApplicationContext()的步骤。
并且多了BeanFactoryPostProcessor接口,如果实现了该接口,ApplicationContext在装载配置文件之后、实例化Bean之前将调用该实现类的方法,对配置信息进行加工处理。Spring框架提供了多个工厂后处理器,如CustomEditorConfigurer、PopertyPlaceholderConfigurer等。工厂后处理器是容器级的,仅在ApplicationContext初始化时调用一次。
ApplicationContext在启动时,将首先为配置文件中的每个<bean>生成一个BeanDefinition对象,BeanDefinition是<bean>在Spring容器中的内部表示。当配置文件中所有的<bean>都被解析为BeanDefinition时,ApplicationContext将调用工厂后处理器的方法,因些,我们有机会通过程序的方式调整Bean的配置信息。
ApplicationContext和BeanFactory的一个最大的不同之处在于,前者会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor及BeanFactoryPostProcessor,并自动将它们注册到ApplicatContext中(在ApplicatContext中,只需在配置文件中通过<bean>定义工厂后处理器和Bean后处理器,它们就会按预期的方式运行);而后者需要在代码中手工调用addBeanProcessor()方法进行注册。
demo2——BeanFactoryPostProcessor
还使用demo1那个例子的代码,添加了MyBeanFactoryPostProcessor的实现、修改了my.xml、修改了测试类
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override // 实现BeanFactoryPostProcessor需要重写的唯一方法 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("car"); beanDefinition.getPropertyValues().addPropertyValue("brand", "吉利博瑞"); System.out.println("调用BeanFactoryPostProcessor的postProcessBeanFactory方法"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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="Car" init-method="myInit" destroy-method="myDestroy" p:brand="宝马373" p:maxSpeed="220"/> <bean class="MyBeanPostProcessor"/> <bean class="MyInstantiationAwareBeanPostProcessor"/> <bean class="MyBeanFactoryPostProcessor"/> </beans>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 测试类 */ public class BeanLifeCycle { public static void main(String[] args) { lifeCycleBeanFactory(); } private static void lifeCycleBeanFactory() { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:my.xml"); Car car1 = (Car)context.getBean("car"); car1.introduce(); car1.setColor("红色"); // 第二次从容器中获取car,直接从缓存池中获取 Car car2 = (Car) context.getBean("car"); // 查看car1和car2是否指向同一引用 System.out.println("car1==car2:" + (car1 == car2)); ((ClassPathXmlApplicationContext)context).destroy(); } }
demo3——BeanFactoryPostProcessor
通过程序的方式调整Bean的配置信息
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.16.RELEASE</version> </dependency>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Driver { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("my.xml"); Boss boss1 = context.getBean("boss1", Boss.class); Boss boss2 = context.getBean("boss2", Boss.class); System.out.println(boss1); System.out.println(boss2); } } class Boss { private Car car; public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } } class Car { }
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; /** * BeanPostProcessor * Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; * Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; * * BeanFactoryPostProcessor * void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; * * BeanPostProcessor和BeanFactoryPostProcessor是两个不同的接口: * BeanPostProcessor是在Bean实例化后、属性设置后执行,是Spring AOP 的赖以实现的基础; * BeanFactoryPostProcessor是WebApplicationContext读取配置文件后,还没有初始化任何实例时运行, * 可以用来修改配置文件 * */ public class UserServiceFactoryBean implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { // 把ConfigurableListableBeanFactory转化为DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; // 通过BeanDefinitionBuilder创建bean定义 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Boss.class); // 设置属性userDao,此属性引用已经定义的bean:car beanDefinitionBuilder.addPropertyReference("car", "car"); // 注册bean定义 beanFactory.registerBeanDefinition("boss1", beanDefinitionBuilder.getRawBeanDefinition()); // 直接注册一个bean实例 beanFactory.registerSingleton("boss2", new Boss()); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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="Car"/> <bean class="UserServiceFactoryBean"/> </beans>