简介
说明
本文介绍Spring中BeanPostProcessor的作用
所有的Bean都会走到BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法。
Spring的Bean的生命周期流程见:Spring–Bean生命周期–流程/原理 – 自学精灵
流程
AbstractApplicationContext#refresh()
registerBeanPostProcessors(beanFactory) //AbstractApplicationContext
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
getBean(String name, Class<T> requiredType) //AbstractBeanFactory
doGetBean(name, requiredType, null, false) //AbstractBeanFactory
createBean(beanName, mbd, args); //AbstractAutowireCapableBeanFactory
doCreateBean(beanName, mbdToUse, args); //AbstractAutowireCapableBeanFactory
BeanPostProcessor的加载顺序
简介
说明
Spring容器启动过程,从向容器注册BeanPostProcessor这一步开始说明:
final class PostProcessorRegistrationDelegate { public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // 注意:此处只会拿到Bean的定义信息。 // 已被实例化的Bean最终都会调用`beanFactory.addBeanPostProcessor`,把这些bean缓存 // 在AbstractBeanFactory的字段beanPostProcessors里,它是个CopyOnWriteArrayList,最终 // 所有BeanPostProcessor都会从这个List里面拿出来执行。 // 本方法的作用是:按顺序,把`BeanPostProcessor`们实例化,然后添加进List。 // 因此顺序是关键:若某些Bean提前被实例化,它就很可能不能被所有的`BeanPostProcessor`处理到了 // (这也是BeanPostProcessorChecker的作用:检查这个然后输出日志的) String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // beanProcessorTargetCount此处赋值后,后续就都不会变了,BeanPostProcessorChecker就是和这个进行比较的。 // beanProcessorTargetCoun = beanFactory里面的Bean实例总个数 + 1(自己)+ bean定义信息~ int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; // 把BeanPostProcessorChecker加进去。它其实做了一个检查而已:输出一个info日志 beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 1、找到同时实现BeanPostProcessor和PriorityOrdered的bean=> getBean=> 排序=> beanFactory.addBeanPostProcessor() // 2、找到同时实现BeanPostProcessor和Ordered的bean,后续步骤同上 // 3、处理没实现排序接口的普通的处理器,不需要sort了,直接add进去。 // 此处代码很多,直接省略。上边三行即描述的此处代码的功能 // 注册一个特殊的处理器 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); } }
代码追踪
写一个自己的后置处理器
package com.example.processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; @Component public class MyProcessor implements BeanPostProcessor, Ordered { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization==> " + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization==> " + beanName); return bean; } }
打断点、启动SpringBoot,
- AutowiredAnnotationBeanPostProcessor它实现了PriorityOrdered接口
- 处理@Autowired,@Value,@Inject
- CommonAnnotationBeanPostProcessor它也实现了PriorityOrdered接口
- 处理@Resource、@PostConstruct、@PreDestroy。
- AsyncAnnotationBeanPostProcessor没有实现任何Orderd排序接口
- MyProcessor此处我们让它实现了Ordered接口
总结
1.自定义的BeanPostProcessor实现类有时可以有时不可以@Autowired来注入一个bean
可以的情况
自定义的BeanPostProcessor实现类没实现顺序接口,或者实现了Ordered接口。而AutowiredAnnotationBeanPostProcessor会负责处理@Autowired,AutowiredAnnotationBeanPostProcessor实现的是靠前的PriorityOrdered,它比没实现顺序接口,或者实现了Ordered接口的后置处理器要实例化的早,所以等到处理到这里的自定义BeanPostProcessor实现类时,可以成功@Autowired来注入一个bean,
不可以的情况
自定义的BeanPostProcessor实现类实现了PriorityOrdered接口。
2.自己定义的BeanPostProcessor实现类可以通过实现ApplicationContextAware接口获得bean
因为这个接口是被ApplicationContextAwareProcessor来解析的,而它已经早早被放进了Spring容器里面,所以通过实现接口的方式任何时候都是可以的。
BeanPostProcessorChecker
BeanPostProcessorChecker是一个BeanPostProcessor,是PostProcessorRegistrationDelegate的一个private static内部类,它的作用就是在postProcessAfterInitialization里检查作用在此Bean上的BeanPostProcessor够不够数,如果不够数(一般是提前加载了,或者被auto-proxying了这种情况就输出一条info日志)。日志示例:trationDelegate$BeanPostProcessorChecker : Bean ‘myBean’ of type [com.example.processor.MyBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
final class PostProcessorRegistrationDelegate { private static final class BeanPostProcessorChecker implements BeanPostProcessor { private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class); // 从if条件可以看出哪些是不需要检测的Bean // 1、BeanPostProcessor类型不检测 // 2、ROLE_INFRASTRUCTURE这种类型的Bean不检测 (Spring自己的Bean) @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) { if (logger.isInfoEnabled()) { logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() + "] is not eligible for getting processed by all BeanPostProcessors " + "(for example: not eligible for auto-proxying)"); } } return bean; } private boolean isInfrastructureBean(@Nullable String beanName) { if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) { BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName); return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE); } return false; } } // 其他代码 }
请先
!