参考文章:
Bean初始化的后置处理器,即BeanPostProcessor 接口
它为我们提供了丰富的可扩展点,它实现了在 Bean 完成实例化后,如果我们需要对其进行一些配置、增加一些自己的处理逻辑
BeanPostProcessor 在源码中的逻辑
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//安全模式
if (System.getSecurityManager() != null) {
// 激活 Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、 BeanFactoryAware
.....
}
else {
// 激活 Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
.....
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 初始化 bean的前置处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 激活初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
.....
return wrappedBean;
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历 BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 处理
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 为空则返回 existingBean
if (current == null) {
return result;
}
result = current;
}
return result;
}
需要注意的时候假如factory中不存在BeanPostProcessor,创建bean的时候则不会触发其内容
BeanPostProcessor 的基本原理
- 可以理解为是 Spring 的一个工厂钩子(如 Aware 、InitializingBean、DisposableBean)
- 一般普通的 BeanFactory 是不支持自动注册 BeanPostProcessor 的,需要我们手动调用 #addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法进行注册
- 但是 ApplicationContext 可以在其 bean 定义中自动检测所有的 BeanPostProcessor 并自动完成注册,同时将他们应用到随后创建的任何 Bean 中
整个Processor的处理逻辑为
Demo
实现BeanPostProcessor接口类
public class BeanPostProcessorTest implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Bean [" + beanName + "] 开始初始化");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Bean [" + beanName + "] 完成初始化");
return bean;
}
public void display(){
System.out.println("hello BeanPostProcessor!!!");
}
}
spring注入bean,但是不添加BeanPostProcessor
public static void main(String[] args) {
//spring2 中注入BeanPostProcessorTest
ClassPathResource resource = new ClassPathResource("spring2.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
BeanPostProcessorTest test = (BeanPostProcessorTest) factory.getBean("beanPostProcessorTest");
test.display();
}
而打印内容
00:35:17.331 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'beanPostProcessorTest' to allow for resolving potential circular references
00:35:17.332 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'beanPostProcessorTest'
hello BeanPostProcessor!!!
spring注入bean,但是添加BeanPostProcessor
public static void main(String[] args) {
//spring2 中注入BeanPostProcessorTest
ClassPathResource resource = new ClassPathResource("spring2.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
BeanPostProcessorTest beanPostProcessorTest = new BeanPostProcessorTest();
// 假如processor后
factory.addBeanPostProcessor(beanPostProcessorTest);
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
BeanPostProcessorTest test = (BeanPostProcessorTest) factory.getBean("beanPostProcessorTest");
test.display();
}
打印内容
00:42:24.778 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'beanPostProcessorTest' to allow for resolving potential circular references
Bean [beanPostProcessorTest] 开始初始化
Bean [beanPostProcessorTest] 完成初始化
00:42:24.780 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'beanPostProcessorTest'
hello BeanPostProcessor!!!
自动注入!!!
spring的application会自动检测processors并注入
AbstractApplicationContext.java中
/**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
- BeanPostProcessor 的作用域是容器级别的,它只和所在的容器相关 ,当 BeanPostProcessor 完成注册后,它会应用于所有跟它在同一个容器内的 bean 。
- BeanFactory 和 ApplicationContext 对 BeanPostProcessor 的处理不同,ApplicationContext 会自动检测所有实现了 BeanPostProcessor 接口的 bean,并完成注册,但是使用 BeanFactory 容器时则需要手动调用 AbstractBeanFactory#addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法来完成注册
- ApplicationContext 的 BeanPostProcessor 支持 Ordered,而 BeanFactory 的 BeanPostProcessor 是不支持的,原因在于ApplicationContext 会对 BeanPostProcessor 进行 Ordered 检测并完成排序,而 BeanFactory 中的 BeanPostProcessor 只跟注册的顺序有关。