什么是BeanPostProcessor
BeanPostProcessor是使用Ioc容器的时经常会遇到的一个特性,这个Bean的后置处理器是一个监听器。将后置处理器向Ioc容器中注册之后,容器中管理的Bean具备了接收Ioc容器事件回调的能力。
BeanPostProcessor是一个接口类,它具有两个接口方法,一个是PostProcessorBeforeInitialization,在Bean的初始化前提供回调入口,一个是postProcessorAfterInitialization,在Bean的初始化后回调入口,这两个回调的触发都和容器Bean的生命周期有关。
applyBeanPostProcessorBeforeInitialization(Object existingBean,String beanName)
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
从方法名上我们就可以看出来这个方法是用来调用调用我们的beanPostBeforeInitialization()方法的,
其中getBeanPostProcessor()方法是用来获取当前容器中已经注册成功的所有BeanPostProcessor,让我们来看看。
/**
* Return the list of BeanPostProcessors that will get applied
* to beans created with this factory.
*/
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
这个方法实现只有一行,直接返回的是beanPostProcessors这个静态变量,那么问题来了,这个静态变量是什么时候被赋值的呢,或者说我们的BeanPostProcessor是什么时候被注册到我们的IOC容器中的呢。让我们回到IOC的启动过程中,在refresh()方法中调用了这样一个方法invokeBeanFactoryPostProcessors();这个方法就是用来注册我们的BeanPostProcessor的,具体的细节我们以后在分析。
既然我们现在知道了postBeforeProcessorInitialization是如何调用的,那么我们现在看一下postAfterProcessorInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
从代码中我们可以看出来,applyBeanPostProcessorAfterInitializa的调用方式和applyBeanPostProcessorsBeforInitialization的调用方式基本相似,都是循环调用before或者after方法。
接下来我们向上看看是由哪个方法调用这两个方法的
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
//这个方法主要是初始化Bean实例,调用在容器的回调方法和Bean的初始化方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//这里就是我们对Bean的后置处理器的postProcessorBeforeInitialization的回调方法的调用
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//调用bean的初始化方法,这个初始化方法是在BeanDefinition中通过init-method属性指定的,同时如果Bean实现了InitializingBean接口,那么这个Bean的afterPropertiesSet实现也会被调用
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//这里就是调用我们的beanPostAfterProcessor的地方
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}