BeanPostProcessor
BeanPostProcessor也称为Bean后置处理器,它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。
BeanPostProcessor的源码如下:
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
其中
方法 | 描述 |
postProcessBeforeInitialization | 方法会在每一个bean对象的初始化方法调用之前回调; |
postProcessAfterInitialization | 方法会在每个bean对象的初始化方法调用之后被回调。具体执行时期可以参考Spring中Bean的生命周期源码探究。 |
查看BeanPostProcessor源码,可以看到它两个方法的参数都相同,其中第一个参数Object bean表示当前正在初始化的bean对象。此外两个方法都返回Object类型的实例,返回值既可以是将入参Object bean原封不动的返回出去,也可以对当前bean进行包装再返回。
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor继承自BeanPostProcessor 是spring非常重要的拓展接口,代表这bean的一段生命周期: 实例化(Instantiation)
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
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;
}
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
方法 | 描述 |
postProcessBeforeInstantiation | 最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走 |
postProcessAfterInstantiation | 在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessProperties方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessProperties就会被忽略不执行;如果返回true,postProcessProperties就会被执行 |
postProcessProperties | 对属性值进行修改,如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改 |
测试:
@Component
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中属性的内容
* 取代过时的postProcessPropertyValues方法
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("<---postProcessProperties--->");
return pvs;
}
}
输出:
Task :spring-demo:RunApp.main()
--->postProcessBeforeInstantiation
<---postProcessAfterInstantiation
<---postProcessProperties--->
postProcessBeforeInitialization
<<postProcessAfterInitialization
SmartInstantiationAwareBeanPostProcessor
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
方法 | 描述 |
predictBeanType | predictBeanType:该触发点发生在postProcessBeforeInstantiation之前,这个方法用于预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null;当你调用BeanFactory.getType(name)时当通过bean的名字无法得到bean类型信息时就调用该回调方法来决定类型信息 |
determineCandidateConstructors | 该触发点发生在postProcessBeforeInstantiation之后,用于确定该bean的构造函数之用,返回的是该bean的所有构造函数列表。用户可以扩展这个点,来自定义选择相应的构造器来实例化这个bean。 |
getEarlyBeanReference | getEarlyBeanReference:该触发点发生在postProcessAfterInstantiation之后,当有循环依赖的场景,当bean实例化好之后,为了防止有循环依赖,会提前暴露回调方法,用于bean实例化的后置处理。这个方法就是在提前暴露的回调方法中触发。 |
测试:
package com.sqz.ioc.beanpostprocess;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Component;
import java.lang.reflect.Constructor;
@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
/**
* 预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null
* @param beanClass
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MySmartInstantiationAwareBeanPostProcessor.predictBeanType,beanName:"+beanName);
return null;
}
/**
* 选择合适的构造器,比如目标对象有多个构造器,在这里可以进行一些定制化,选择合适的构造器
*
* @param beanClass : beanClass参数表示目标实例的类型
* @param beanName : beanName是目标实例在Spring容器中的name
* @return : 返回值是个构造器数组,如果返回null,会执行下一个PostProcessor的determineCandidateConstructors方法;否则选取该PostProcessor选择的构造器
* @throws BeansException
*/
@Override
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MySmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors,beanName:"+beanName);
return null;
}
/**
* 获得提前暴露的bean引用,主要用于解决循环引用的问题
* (只有单例对象才会调用此方法)
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
System.out.println("MySmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference,beanName:"+beanName);
return null;
}
}
MergedBeanDefinitionPostProcessor
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
* Post-process the given merged bean definition for the specified bean.
* @param beanDefinition the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
* @see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* A notification that the bean definition for the specified name has been reset,
* and that this post-processor should clear any metadata for the affected bean.
* <p>The default implementation is empty.
* @param beanName the name of the bean
* @since 5.1
* @see DefaultListableBeanFactory#resetBeanDefinition
*/
default void resetBeanDefinition(String beanName) {
}
}
方法 | 描述 |
postProcessMergedBeanDefinition | 创建完 bean 实例之后,填充属性之前调用 一般做注解扫描 |
resetBeanDefinition | DefaultListableBeanFactory # registerBeanDefinition调用 一般做移除缓存 |
DefaultListableBeanFactory # registerBeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// S1 : 会对 BeanDefinition 进行校验 , 主要是MethodOverrides和FactoryMethodName不能同时存在
// -- 工厂方法必须创建具体的 Bean 实例 , 而 methodOverrides 会创建代理类且进行增强
// -- 也就是说 工厂需要实例 , 不能是代理类
if (beanDefinition instanceof AbstractBeanDefinition) {
((AbstractBeanDefinition) beanDefinition).validate();
}
// S2 : 判断 BeanDefinition 是否已经存在
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 是否允许同名Bean重写 , 因为此处已经存在一个了 , 不能重写则直接异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// 角色比较 ,只打日志
// ROLE_APPLICATION / ROLE_SUPPORT / ROLE_INFRASTRUCTURE
}else if (!beanDefinition.equals(existingDefinition)) {
// 判断是否为同一对象
}
// 以上主要是打log , 这里如果允许覆盖则直接覆盖了
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 判断该Bean是否已经开始初始化
if (hasBeanCreationStarted()) {
// 如果已经开始 , 需要对 Map 上锁后再处理
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
// 省略一些更新操作
}
}
else {
// 没有加载时的载入
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// 如果Bean已经存在或已经开始加载了 , 这个时候时需要进行销毁操作的
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
protected void resetBeanDefinition(String beanName) {
// S1 : 如果已经创建 ,需要清空 Merge BeanDefinition
clearMergedBeanDefinition(beanName);
// S2 : 销毁 Bean
destroySingleton(beanName);
// S3 : 调用 PostProcessors 重置处理器进行处理
for (BeanPostProcessor processor : getBeanPostProcessors()) {
if (processor instanceof MergedBeanDefinitionPostProcessor) {
((MergedBeanDefinitionPostProcessor) processor).resetBeanDefinition(beanName);
}
}
// S4 : 如果该 BeanDefinition 是某个BeanDefinition 的Parent , 则需要同步处理
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
if (bd != null && beanName.equals(bd.getParentName())) {
resetBeanDefinition(bdName);
}
}
}
}