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.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
可以看到程序的执行顺序为”构造函数
->setter
->BeanPostProcessor#postProcessBeforeInitialization
->init-method
->BeanPostProcessor#postProcessAfterInitialization
“,从这个执行顺序基本可以得出结论,这里的post是相对于构造函数来说的,即在构造函数之后,initiallization
指的是init-method
。从结果可以看到,ApplicationContext确实自动注册了,源码如下:
org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
...snip...
if (refresh) {
refresh();
}
}
org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...snip...
try {
...snip...
// 注册用于拦截处理bean创建的BeanPostProcessor
registerBeanPostProcessors(beanFactory);
...snip...
}
}
}
org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取bean工厂容器中所有的BeanPostProcessor实例的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// BeanPostProcessor的总个数
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 注册BeanPostProcessorChecker类型的BeanPostProcessor
// 执行日志记录相关内容
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 存储通过PriorityOrder接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 记录MergedBeanDefinitionPostProcessor类型的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 记录实现了Order接口的BeanPostProcessor
List<String> orderedPostProcessorNames = new ArrayList<>();
// 记录既没有实现PriorityOrdered接口也没有实现Ordered接口的BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// 如果是PriorityOrder类型,则添加到priorityOrderedPostProcessors
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 如果是MergedBeanDefinitionPostProcessor类型则添加到
// internalPostProcessors
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 如果是Ordered接口类型,则添加到orderedPostProcessorNames
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// 否则,添加到nonOrderedPostProcessorNames
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 排序实现了PriorityOrdered接口的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 注册实现了PriorityOrdered接口的BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 根据名称获取实现了Ordered接口的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 排序实现了Oredered接口的BeanPostProcessor
sortPostProcessors(orderedPostProcessors, beanFactory);
// 注册实现了Ordered接口的BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 获取所有的即没有实现Ordered接口,也没有实现PriorityOrdered接口的
// 普通的BeanPostProcesssor实例
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册普通BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 排序所有的MergeBeanDefinitionPostProcessor类型的BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
// 注册所有的MergeBeanDefinitionPostProcessor类型的BeanPostProcessor,调用AbstractBeanFacotry#addBeanPostProcesssor
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
3:InstantiationAwareBeanPostProcessor
这是BeanPostProcessor的一个子接口,翻译过来是实例化感知的bean后置处理器
,大概意思就是在通过构造函数创建实例对象的前后加入一些操作
,其实就是扩展了BeanPostProcessor
的功能,接口定义如下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
// 在调用构造方法之前,执行该方法,分为以下两种情况
// 1:如果是不想要默认生成的对象,则可以在这里创建,然后返回
// 2:如果是不想干预默认对象的生成,则直接返回null即可
// 一般这里我们都会返回null,default实现也是返回null,因此,
// 在实际使用中可以忽略该方法,不需要实现
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
// 该方法在构造函数执行之后执行,分为以下两种情况
// 1:如果是希望后续继续填充属性信息,则返回true
// 2:如果是不希望填充属性信息,则返回false
// 正常都是返回true,这里的default实现也是如此,因此,
// 在实际使用中可以忽略该方法,不需要是实现
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
// 暂时忽略
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
// 在填充属性之前执行,最后一次修改属性信息的机会
// 如果是希望修改属性信息,则可以在这里完成,否则
// 直接返回传入参数中的ProperyValues就可以了
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
3.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 中自定义的初始化方法");
}
}
3.2:定义自定义后置bean处理器
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
* BeanPostProcessor接口中的方法
* 在Bean的自定义初始化方法之前执行
* Bean对象已经存在了
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println(">>postProcessBeforeInitialization");
return bean;
}
/**
* BeanPostProcessor接口中的方法
* 在Bean的自定义初始化方法执行完成之后执行
* Bean对象已经存在了
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("<<postProcessAfterInitialization");
return bean;
}
/**
* InstantiationAwareBeanPostProcessor中自定义的方法
* 在方法实例化之前执行 Bean对象还没有
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("--->postProcessBeforeInstantiation");
return null;
}
/**
* InstantiationAwareBeanPostProcessor中自定义的方法
* 在方法实例化之后执行 Bean对象已经创建出来了
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("<---postProcessAfterInstantiation");
return true;
}
/**
* InstantiationAwareBeanPostProcessor中自定义的方法
* 可以用来修改Bean中属性的内容
*/
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
String beanName) throws BeansException {
System.out.println("<---postProcessPropertyValues--->");
return pvs;
}
}
3.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.MyInstantiationAwareBeanPostProcessor"/>
</beans>
3.4:ApplicationContext测试
@Test
public void testBeanPostProcessor() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("testbeandefinition.xml");
ac.getBean("user");
}
运行:
--->postProcessBeforeInstantiation
User 被实例化
<---postProcessAfterInstantiation
<---postProcessPropertyValues--->
设置:波波烤鸭
>>postProcessBeforeInitialization
User 中自定义的初始化方法
<<postProcessAfterInitialization
相比于BeanPostProcessor
多了,实例化前,实例化后,属性设置前
这三个干预bean创建的方法。我们来看对比下二者的执行情况:
执行时期 | BeanPostProcessor | InstantiationAwareBeanPostProcessor |
---|---|---|
实例化前 | 不支持 | postProcessBeforeInstantiation |
实例化后 | 不支持 | postProcessAfterInstantiation |
属性设置前 | 不支持 | postProcessPropertyValues |
初始化方法前 | postProcessBeforeInitialization | postProcessBeforeInitialization |
初始化方法前 | postProcessAfterInitialization | postProcessAfterInitialization |