spring BeanFactory及ApplicationContext中Bean的生命周期

2022-11-04,,,,

spring bean 的生命周期

spring BeanFactoryApplicationContext在读取配置文件后、实例化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>

pom.xml

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方法");
}
}

Car.java

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;
}
}

MyInstantiationAwareBeanPostProcessor

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;
}
}

MyBeanPostProcessor

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

my.xml

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方法");
}
}

MyBeanFactoryPostProcessor

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

my.xml

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>

pom.xml

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>

spring BeanFactory及ApplicationContext中Bean的生命周期的相关教程结束。

《spring BeanFactory及ApplicationContext中Bean的生命周期.doc》

下载本文的Word格式文档,以方便收藏与打印。