BeanPostProcessor 的用法
BeanPostProcessor
是 Spring 对外提供的一个扩展,用于在 bean 初始化阶段对 bean 做一些特殊的处理。
BeanPostProcessor 的定义及作用
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
BeanPostProcessor
中定义两个方法,postProcessBeforeInitialization
和 postProcessAfterInitialization
,调用时机分别是在 bean 被初始化之后,继承自 InitializingBean
的 afterPropertiesSet
方法或者 xml 文件中定义的 init-method
方法被调用之前,而 postProcessAfterInitialization
是在这种 callback 方法被调用之后执行。
如下图所示(简书上没法解析有道云的流程图语法):
graph TD
A[Bean 实例化/ 设置属性 / 回调 Aware 等操作] --> B[调用 postProcessBeforeInitialization]
B --> C[调用 afterPropertiesSet / init-method 等回调方法]
C --> D[调用 postProcessAfterInitialization 方法]
D --> E[其他操作...]
BeanPostProcessor 的源码分析
bean 的初始化是在 refresh
方法中进行的,首先将 BeanPostProcessor
注册到 BeanFactory
中,在执行 initializeBean
的时候再调用,注册是在 registerBeanPostProcessors(beanFactory)
进行的:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
继续查看 registerBeanPostProcessors
方法:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有的 BeanPostProcessor bean 名字
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// ...
// 根据不同的优先级,内部 processor 以及 Order 排序,再处理
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
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);
}
}
// 先注册实现了 PriorityOrdered 接口的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
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);
}
}
// 再注册实现了 Ordered 接口的
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 然后注册没有指定优先级的
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);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后注册内部的
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 最后添加一个 Spring 自带的
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
在 bean 初始化时候调用 postProcessBeforeInitialization
和 postProcessAfterInitialization
:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 处理 Aware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// 先调用 postProcessBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 再调用 afterPropertiesSet / init-method 等回调方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 最后调用 postProcessAfterInitialization
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
BeanPostProcessor 的应用场景
Spring 内部使用 BeanPostProcessor
来进行 bean 的增强,比如 AOP,Dubbo 中也使用 BeanPostProcessor
来实现 @Reference
注解的对象注入。
在我做过的项目中,使用 BeanPostProcessor
进行了和 Dubbo 类似的操作,对自定义注解进行了注入,比如定义了一个 @Person
注解,在 postProcessBeforeInitialization
中读取传入的 bean 是不是符合要求的,如果是符合要求的,注入一个自定义的对象到 bean 中标注了 @Person
注解的属性中。