1:作用
在spring bean的生命周期中加入自定义逻辑。
2:接口
源码:
public interface BeanPostProcessor {
// 该方法在调用完毕构造方法,setter方法后,执行init-method方法前
// 执行,参数为当前状态下的bean,以及bean的名称
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 该方法在init-method方法调用完毕后执行
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
2:例子
在BeanFactory中不会自动注册自定义的BeanPostProcessor,需要通过API添加,但是在ApplicationContext体系中会自动检测并添加调用。
2.1:定义Bean
public class User {
private int id;
private String name;
private String beanName;
public User() {
System.out.println("User 被实例化");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("设置:"+name);
this.name = name;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
/**
* 自定义的初始化方法
*/
public void start() {
System.out.println("User 中自定义的初始化方法");
}
}
2.2:定义自定义后置bean处理器
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("before--实例化的bean对象:"+bean+"\t"+beanName);
// 可以根据beanName不同执行不同的处理操作
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("after...实例化的bean对象:"+bean+"\t"+beanName);
// 可以根据beanName不同执行不同的处理操作
return bean;
}
}
2.3:配置文件
<?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 class="yudaosourcecode.postprocessor.User" id="user" init-method="start">
<property name="name" value="波波烤鸭" />
</bean>
<!-- 注册处理器 -->
<bean class="yudaosourcecode.postprocessor.MyBeanPostProcessor"/>
</beans>
2.4:BeanFactory测试
@Test
public void testBeanDefinitionWithBeanFacotry() {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("testbeandefinition.xml"));
xbf.getBean("user");
}
运行:
User 被实例化
设置:波波烤鸭
User 中自定义的初始化方法
此时可以看到自定义的后置bean处理器并没有生效,修改代码,手动添加后置bean处理器:
@Test
public void testBeanDefinitionWithBeanFacotry() {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("testbeandefinition.xml"));
xbf.addBeanPostProcessor(new MyBeanPostProcessor());
xbf.getBean("user");
}
运行:
User 被实例化
设置:波波烤鸭
before--实例化的bean对象:yudaosourcecode.postprocessor.User@610694f1 user
User 中自定义的初始化方法
after...实例化的bean对象:yudaosourcecode.postprocessor.User@610694f1 user
可以看到此时后置bean处理器就生效了。
我们就着BeanFactory来看下多个后置处理器的情况,再定义一个:
public class MyBeanPostProcessor1 implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("111before--实例化的bean对象:"+bean+"\t"+beanName);
// 可以根据beanName不同执行不同的处理操作
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("111after...实例化的bean对象:"+bean+"\t"+beanName);
// 可以根据beanName不同执行不同的处理操作
return bean;
}
}
修改测试代码:
@Test
public void testBeanDefinitionWithBeanFacotry() {
XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource("testbeandefinition.xml"));
xbf.addBeanPostProcessor(new MyBeanPostProcessor());
xbf.addBeanPostProcessor(new MyBeanPostProcessor1());
xbf.getBean("user");
}
运行:
User 被实例化
设置:波波烤鸭
before--实例化的bean对象:yudaosourcecode.postprocessor.User@610694f1 user
111before--实例化的bean对象:yudaosourcecode.postprocessor.User@610694f1 user
User 中自定义的初始化方法
after...实例化的bean对象:yudaosourcecode.postprocessor.User@610694f1 user
111after...实例化的bean对象:yudaosourcecode.postprocessor.User@610694f1 user
可以看到调用过程使用的是典型的责任链方式完成的,before先执行的后执行after。
2.5:ApplicationContext测试
@Test
public void testBeanDefinitionWithApplicationContext() {
ApplicationContext ac = new ClassPathXmlApplicationContext("testbeandefinition.xml");
ac.getBean(User.class);
}
运行:
User 被实例化
设置:波波烤鸭
before--实例化的bean对象:yudaosourcecode.postprocessor.User@28ac3dc3 user
User 中自定义的初始化方法
after...实例化的bean对象:yudaosourcecode.postprocessor.User@28ac3dc3 user