一、BeanPostProcessor 扩展接口
BeanPostProcessor
是Spring
中的一个扩展接口,它可以在Spring
容器实例化bean
之后,在执行 bean
的初始化方法前后,允许我们自定义修改新的 bean
实例。比如修改 bean
的属性,将 bean
替换为动态代理等。其中 AOP
的底层创建代理实例,就是通过实现 BeanPostProcessor
来实现的。
BeanPostProcessor
包含两个方法:
public interface BeanPostProcessor {
/**
* 实例化及依赖注入完成后、bean 初始化方法触发之前执行
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* bean 初始化方法触发后执行
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
如果在 Bean
实例化、配置和其他初始化过程中有任何错误,由 Spring
抛出 BeansException
异常。由于 BeanPostProcessor
可以干预 Bean
实例化、配置和初始化的每个阶段,因此实现过程需要非常谨慎。
BeanPostProcessor
是怎么干预 Bean
实例化的呢?可以通过下面这个案例感受一下:
这里我们创建一个测试 bean
:
@Component
public class Test {
public void test() {
System.out.println("test...");
}
}
下面创建一个类实现 BeanPostProcessor
接口,在后通知中使用 CGLIB
创建一个动态代理对象:
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
/**
* 实例化及依赖注入完成后、bean 初始化方法触发之前执行
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* bean 初始化方法触发后执行
*/
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
Class beanClass = bean.getClass();
if (beanClass == Test.class) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanClass);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("<目标方法之前开始执行....>");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("<目标方法之后开始执行....>");
return result;
});
return enhancer.create();
}
return bean;
}
}
下面测试下效果:
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("com.example.demo.beanpost");
Test hello = (Test) context.getBean("test");
hello.test();
}
}
这样是不是就感受到 BeanPostProcessor
扩展接口的强大之处了吧,可以看出它可以干预 Bean
的实例化,因此使用的话需要非常谨慎。
下面从源码角度分析下,在 Spring 中是如何使用 BeanPostProcessor
进行扩展的。
二、BeanPostProcessor 的注册
从上面的实例中可以感觉出来,我们并没有对 BeanPostProcessor
进行特殊处理,仅仅将其加入 Spring
容器中即会生效,那 Spring
是如何读取BeanPostProcessor
呢?
在本专栏的其他 Spring
源码分析的文章中,分析的入口都是基于 AbstractApplicationContext
中的 refresh()
方法,那现在也是从这里入手,主要逻辑在该方法下触发的 registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
方法:
主要逻辑则在 PostProcessorRegistrationDelegate
下的 registerBeanPostProcessors
方法,源码如下:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 从bean工厂中获取到所有实现了 BeanPostProcessor 接口的 beanName
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 往bean工厂中添加一个BeanPostProcessor -> BeanPostProcessorChecker
// BeanPostProcessorChecker 是一个在创建bean期间记录信息消息的 BeanPostProcessor
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 存放实现了PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
// 存放实现了MergedBeanDefinitionPostProcessor接口的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
// 存放实现了Ordered接口的BeanPostProcessor
List<String> orderedPostProcessorNames = new ArrayList<String>();
// 存放普通的BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
// 如果实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 从工厂中获取对应的 Bean实例
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 如果同时实现了MergedBeanDefinitionPostProcessor接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 如果实现了Ordered接口
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// 普通的 BeanPostProcessor
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 排序
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 注册实现了PriorityOrdered 接口的 BeanPostProcessor
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
// 如果同时实现了MergedBeanDefinitionPostProcessor接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 排序
sortPostProcessors(beanFactory, orderedPostProcessors);
// 注册实现了Ordered接口的BeanPostProcessor
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 注册其他普通的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
// 如果实现了 MergedBeanDefinitionPostProcessor 接口
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 通过 beanFactory.addBeanPostProcessor(postProcessor) 添加 BeanPostProcessor
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 排序
sortPostProcessors(beanFactory, internalPostProcessors);
// 通过beanFactory.addBeanPostProcessor(postProcessor)添加BeanPostProcessor
// 注册所有 BeanPostProcessor
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).
// 往bean工厂中添加一个BeanPostProcessor -> ApplicationListenerDetector
// ApplicationListenerDetector主要是检测bean是否实现了ApplicationListener接口
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
三、BeanPostProcessor 触发点
BeanPostProcessor
与 bean
的实例化息息相关,因此可以从 bean
实例化的入口 AbstractAutowireCapableBeanFactory
类的 createBean
方法入手:
3.1 resolveBeforeInstantiation
首先是 createBean
方法下触发的 resolveBeforeInstantiation
方法:
在这会尝试通过 BeanPostProcessors
获取一个对象,这个可能是代理实例也可能是其他实例:
这里判断如果有 InstantiationAwareBeanPostProcessor
类型的 BeanPostProcessor
,则尝试使用 postProcessBeforeInstantiation
方法获取一个代理实例。
3.2 getEarlyBeanReference
如果上面没有代理实例的话,在回到 createBean
方法中,在 doCreateBean
方法中,创建实例后,会放入三级缓存中:
在 getEarlyBeanReference
方法中,会尝试使用 SmartInstantiationAwareBeanPostProcessor
类型的 BeanPostProcessor
创建一个早期的实例,虽说 SmartInstantiationAwareBeanPostProcessor
没有直接实现 BeanPostProcessor
但其父类 InstantiationAwareBeanPostProcessor
实现了 BeanPostProcessor
:
Spring AOP
代理对象就是在此处获取,因此三级缓存存入ObjectFactory<?>
而不是具体的 bean
的意义在此。
3.3 initializeBean
上面都是对特殊类型的 BeanPostProcessor
进行触发,在 doCreateBean
的 initializeBean
中则触发了全部的BeanPostProcessor
:
这里在 invokeInitMethods
方法前后触发了 BeanPostProcessor
的 postProcessBeforeInitialization
和 postProcessAfterInitialization
:
四、Spring 中的 BeanPostProcessor 常用子类
从上面的触发点源码中,可以看出有些地方是触发的特定类型的 BeanPostProcessor
子类,而这些子类又有着不同的用途。
4.1 InstantiationAwareBeanPostProcessor
可以在Bean
生命周期实例化Bean
之前和实例化Bean
之后对Bean
进行操作,比如在上面源码中 createBean
方法下触发的 resolveBeforeInstantiation
方法。
InstantiationAwareBeanPostProcessor
类型的子类,会在目标Bean
实例化之前尝试使用该类型的实例生成一个代理对象,如果方法返回的是一个非空对象, 将会跳过后续 Spring
默认的创建流程:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
// 在目标Bean实例化之前执行尝试使用该类型的生成一个代理对象,如果方法返回的是一个非空对象, 将会跳过后续 Spring 默认的创建流程
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
// 在目标Bean实例化之后、属性填充前执行,如果方法返回false,将会跳过后续的属性填充过程,通常情况下返回true
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;
}
// 对属性值进行修改,通过基于原始的PropertyValues创建一个新的MutablePropertyValues实例,添加或删除特定的值
// 已标记过期,官方推荐使用 postProcessProperties()方法
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
4.2 SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
也是一个接口继承了上面的 InstantiationAwareBeanPostProcessor
因此拥有 InstantiationAwareBeanPostProcessor
的特征,在此之外又提供了获取早期实例的方法。
在 Spring
的三级缓存中则会尝试使用 getEarlyBeanReference
获取一个早期实例。
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
//在 Bean 实例化前预测最终返回的 Class 类型,触发时机是在InstantiationAwareBeanPostProcessor的 postProcessBeforeInstantiation()之前
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//决定使用哪个构造器构造Bean,如果不指定,默认为null,即bean的无参构造方法;
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
//获得提前暴露的bean引用,主要用于 Spring 循环依赖问题的解决
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
4.3 ApplicationContextAwareProcessor
应用上下文感知Bean
后置处理器,在postProcessBeforeInitialization
方法中通过invokeAwareInterfaces
方法给目标 Bean
注入指定的属性值:
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)) {
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
// 给bean设置Environment属性
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
// 给bean设置EmbeddedValueResolver属性
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
// 给bean设置ResourceLoader属性
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
// 给bean设置ApplicationEventPublisher属性
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
// 给bean设置MessageSource属性
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
// 给bean设置 ApplicationStartupAware属性
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
// 给bean设置ApplicationContext属性
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
4.4 ApplicationListenerDetector
判断目标 Bean
是否实现 ApplicationListener
,如果有则注册事件:
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);
private final transient AbstractApplicationContext applicationContext;
private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);
public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (ApplicationListener.class.isAssignableFrom(beanType)) {
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// 添加事件
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
try {
ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
multicaster.removeApplicationListener((ApplicationListener<?>) bean);
multicaster.removeApplicationListenerBean(beanName);
}
catch (IllegalStateException ex) {
// ApplicationEventMulticaster not initialized yet - no need to remove a listener
}
}
}
@Override
public boolean requiresDestruction(Object bean) {
return (bean instanceof ApplicationListener);
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof ApplicationListenerDetector &&
this.applicationContext == ((ApplicationListenerDetector) other).applicationContext));
}
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.applicationContext);
}
}