BeanPostProcessor
BeanPostProcessor是Spring一个非常重要的扩展接口,它使得在创建bean实例的前后做一些扩展处理。
public interface BeanPostProcessor {
/**
在任何bean初始化回调(比如InitializingBean的{@code afterPropertiesSet}或自定义
init-method)之前,将这个BeanPostProcessor应用到给定的新bean实例。bean已经被填充了属性值。
返回的bean实例可能是原始bean的包装器。
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
在任何bean初始化回调(比如InitializingBean的{@code afterPropertiesSet}或自定义init-method)
之后,将这个BeanPostProcessor应用到给定的新bean实例。bean已经被填充了属性值。
返回的bean实例可能是原始bean的包装器。对于FactoryBean,这个回调将被FactoryBean实例和FactoryBean
创建的对象调用(从Spring 2.0开始)。后处理器可以决定是应用于FactoryBean还是创建的对象,或者通过相应的
{@code bean instanceof FactoryBean}检查应用于两者。这个回调也将在{@link
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}方法触发短路后调用, 这与所有其他的BeanPostProcessor回调不同。
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
要使用BeanPostProcessor,就必须在Spring容器中注册其实现类。
Spring中注册BeanPostProcessor
在AbstractApplicationContext#registerBeanPostProcessors方法中,Spring进行了BeanPostProcessor的注册操作。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//去容器里面找到所有类型为BeanPostProcessor的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//记录所有的beanProcessor数量,在这之前也可能注册了一部分Spring内部的BeanPostProcessors接口,例如:ApplicationContextAwareProcessor
int beanProcessorTargetCount =
beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(
new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 记录优先级最高的BeanPostProcessors集合,这类最先调用;需要实现PriorityOrdered接口
List<BeanPostProcessor> priorityOrderedPostProcessors =
new ArrayList<BeanPostProcessor>();
// 记录内部BeanPostProcessors集合
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
// 记录实现了Ordered接口的BeanPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<String>();
// 记录普通的没有实现Ordered接口的BeanPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
// 下面的这些代码就是遍历所有postProcessorNames,按优先级排序;类型PriorityOrdered>Ordered>普通;在这个类型基础上,还要对他们的order属性就行排序;
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 实例化实现PriorityOrdered接口的BeanPostProcessor实现类
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
// 实例化实现Ordered接口的BeanPostProcessor实现类
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
//注册 BeanPostProcessor beans。容器中beanPostProcessors是一个ArrayList来持有这些BeanPostProcessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors =
new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
// 实例化没有实现Ordered接口的BeanPostProcessor实现类
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(
new ApplicationListenerDetector(applicationContext));
}
//PostProcessorRegistrationDelegate#registerBeanPostProcessors(ConfigurableListableBeanFactory, List<BeanPostProcessor>)
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors){
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
// AbstractBeanFactory#addBeanPostProcessor
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
// 为什么会专门做instanceof InstantiationAwareBeanPostProcessor的判断呢?下面会继续讲解
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
上面的代码逻辑很简单,就是对BeanPostProcessor进行分类,并根据先后是否实现PriorityOrdered、Ordered、无Ordered的类别依次执行实例化,并将其实例化的实例记录到AbstractBeanFactory#beanPostProcessors中。
BeanPostProcessor方法的执行时期
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
System.out.println("MyBeanPostProcessor实例化了");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor -> " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor -> " + beanName);
return bean;
}
}
编写Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<bean class="com.spring.postprocessor.bean.MyBeanPostProcessor"/>
<bean id="person" class="com.spring.beans.Person">
<property name="name" value="zhangsan"/>
<property name="age" value="20"/>
<property name="sex" value="man"/>
</bean>
</beans>
测试代码
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = context.getBean(Person.class);
System.out.println(person);
context.close();
}
通过debug,可以发现MyBeanPostProcessor进行初始化的起始位置为:
PostProcessorRegistrationDelegate.registerBeanPostProcessors(ConfigurableListableBeanFactory, AbstractApplicationContext) line: 237
MyBeanPostProcessor.postProcessBeforeInitialization(Object, String)方法调用的位置为:
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(
Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
result = processor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
此方法的调用是在bean实例化后,在初始化之前执行。
MyBeanPostProcessor.postProcessAfterInitialization(Object, String)方法调用的位置为:
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(
Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
result = processor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
此方法的调用是在bean实例化后,且在初始化之后执行。
BeanPostProcessor使用场景
BeanPostProcessor典型的应用场景时在AOP生成代理对象的时候,AOP代理需要创建被代理类的对象,才能对对象进行代理。根据代理的特点,通过在BeanPostProcessor#postProcessAfterInitialization方法执行的时候,对被代理对象进行增强,这样就可以生成新的代理对象。
当然还有其他应用场景,比如使用org.springframework.beans.factory.annotation.Autowired进行注入对象的饿时候,也是通过BeanPostProcessor完成。
具体代码使用场景的代码就不在这里分析了,后面在开单独文章进行AOP或@Autowired应用分析。
InstantiationAwareBeanPostProcessor
/**
此接口是BeanPostProcessor的子接口,用于在实例化钱回调和在实例化后但在显示属性设置或之前的回调自动装配。
这个接口是一个特殊用途的接口,主要用于框架内的内部使用。建议尽可能使用BeanPostProcessor接口
*/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
在目标bean被实例化之前应用这个BeanPostProcessor。返回的bean对象可以是一个代理来代替目标bean,
有效地抑制目标bean的默认实例化。如果此方法返回非空对象,则创建bean的过程将被短路。
*/
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
/**
通过构造函数或工厂方法实例化bean后执行操作,但在Spring属性填充(来自显式属性或自动装配)发生之前。
这是在给定bean上执行自定义字段注入的理想回调。例如,就在Spring的自动装配开始之前。创建的bean实例,
属性尚未设置。
*/
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
/**
在工厂应用给定的属性值之前,对它们进行后处理到给定的bean。允许检查是否所有依赖项已被满足。
还允许替换要应用的属性值,通常通过根据原始的PropertyValues创建一个新的MutablePropertyValues
实例,添加或删除特定值。
*/
PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
}
和BeanPostProcessor是在Bean实例化之后进行操作不同,InstantiationAwareBeanPostProcessor是在Bean实例化之前进行操作。具体地说:
对于Bean可以大概分为两部分:
(1)实例化。实例化的过程是一个创建Bean的过程,即调用Bean的构造函数。
(2)初始化。初始化的过程是一个赋值的过程,设置Bean的属性。
InstantiationAwareBeanPostProcessor是在”(1)“前后进行操作的。
BeanPostProcessor是在“(2)”前后进行操作的。
InstantiationAwareBeanPostProcessor方法的执行时期
//AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
//...
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
//...
// 如果resolveBeforeInstantiation返回的bean==null,则进行下面的创建bean的操作。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
//AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//...
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
//...
return bean;
}
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
result = processor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
从上面的代码中可以看出,如果resolveBeforeInstantiation返回一个实例,那么会对下面创建bean的逻辑进行”短路“操作。
下面进行代码演示。
编写InstantiationAwareBeanPostProcessor实现类
public class MyInstantiationAwareBeanPostProcessor implements
InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(
"MyInstantiationAwareBeanPostProcessor#postProcessBeforeInitialization ->" + beanName + "执行了");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(
"MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization ->" + beanName + "执行了");
return bean;
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println(
"MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation ->" + beanName + "执行了");
return new Person("lisi", 30, "man");
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println(
"MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation ->" + beanName + "执行了");
return false;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,String beanName) throws BeansException {
return pvs;
}
}
编写Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<bean class="com.spring.postprocessor.bean.MyInstantiationAwareBeanPostProcessor"/>
<bean id="person" class="com.spring.beans.Person">
<property name="name" value="zhangsan"/>
<property name="age" value="20"/>
<property name="sex" value="man"/>
</bean>
</beans>
测试代码
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = context.getBean(Person.class);
System.out.println(person);
context.close();
}
输出结果:
MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation ->person执行了
MyInstantiationAwareBeanPostProcessor#postProcessAfterInitialization ->person执行了
Person(name=lisi, age=30, sex=man)
输出的Person是name=lisi,而不是zhangsan,说明MyInstantiationAwareBeanPostProcessor对后面的执行做了短路操作了。
InstantiationAwareBeanPostProcessor应用场景
InstantiationAwareBeanPostProcessor在平常的开发中基本上不会使用,更多的是应用于框架层面,如实现Spring在实现AOP的时候。在日常开发中,更多的是使用BeanPostProcessor接口。
https://blog.csdn.net/u010634066/article/details/80321854