BeanPostProcessor 源码分析

BeanPostProcessor 接口也叫 Bean 后置处理器,作用是在 Bean 对象实例化和依赖注入完成后,在配置文件 bean 的 init-method(初始化方法)或者 InitializingBean 的 afterPropertiesSet 的前后添加我们自己的处理逻辑。注意是 Bean 实例化完毕后及依赖注入完成后触发的,接口的源码如下。

  1. public interface BeanPostProcessor {
  2. /**
  3. * 实例化、依赖注入完毕,
  4. * 在调用显示的初始化之前完成一些定制的初始化任务
  5. */
  6. Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
  7. /**
  8. * 实例化、依赖注入、初始化完毕时执行
  9. */
  10. Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
  11. }

共有两种方式实现:

  • 实现 BeanPostProcessor 接口,然后将此类注册到 Spring 即可;
  • 第二种是通过ConfigurableBeanFactory 的 addBeanPostProcessor 方法进行注册。

BeanPostProcess 可以有多个,并且可以通过设置 order 属性来控制这些 BeanPostProcessor 实例的执行顺序。 仅当 BeanPostProcessor 实现 Ordered 接口时,才能设置此属性,或者 PriorityOrdered 接口。

如果某个类实现了 BeanPostProcessor 则它会在 AbstractApplicationContext 中的 registerBeanPostProcessors(beanFactory)方法中创建 bean 而不是和普通的 bean 一样在 finishBeanFactoryInitialization(beanFactory)中才被创建。

当我们注册 BeanPostProcessor 的时候,其中我省略了大部分无关代码:

  1. public static void registerBeanPostProcessors(
  2. ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
  3. // 找到实现BeanPostProcessor接口的子类bean名称
  4. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
  5. // 加一是因为下一行又加了一个BPP(BeanPostProcessor)
  6. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
  7. beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
  8. // 排序省略,没啥好讲的,你只需要知道没有实现排序接口的BPP放在了nonOrderedPostProcessorNames这里
  9. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  10. List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
  11. List<String> orderedPostProcessorNames = new ArrayList<>();
  12. List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  13. for (String ppName : postProcessorNames) {
  14. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  15. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  16. priorityOrderedPostProcessors.add(pp);
  17. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  18. internalPostProcessors.add(pp);
  19. }
  20. }
  21. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  22. orderedPostProcessorNames.add(ppName);
  23. }
  24. else {
  25. nonOrderedPostProcessorNames.add(ppName);
  26. }
  27. }
  28. // 中间省略了一些....
  29. // 重点来了
  30. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
  31. for (String ppName : nonOrderedPostProcessorNames) {
  32. // 当它getBean的时候我们的BPP就开始创建
  33. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  34. nonOrderedPostProcessors.add(pp);
  35. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  36. internalPostProcessors.add(pp);
  37. }
  38. }
  39. }

在此我举例一个典型的例子 AutowiredAnnotationBeanPostProcessor,是 BeanPostProcessor 的一个子类,是@Autowired 和@Value 的具体实现,其他的子类你也可以按如下的流程自行走一边,注意我的例子只是一个最为简单的例子,也就是用@Autowired 注入了一个普通的字段对象

我们看看 AutowiredAnnotationBeanPostProcessor 类,当然也是省略大部分代码:

  1. // 这个类可以看见当我们创建AutowiredAnnotationBeanPostProcessor对象的时候完成了一个工作就是给
  2. // autowiredAnnotationTypes赋值,这个操作有点超前,后面根据这个判断要注入的类中是否有如下的注解
  3. public AutowiredAnnotationBeanPostProcessor() {
  4. this.autowiredAnnotationTypes.add(Autowired.class);
  5. this.autowiredAnnotationTypes.add(Value.class);
  6. try {
  7. this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
  8. ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
  9. logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
  10. }
  11. catch (ClassNotFoundException ex) {
  12. // JSR-330 API not available - simply skip.
  13. }
  14. }
  15. // 从InstantiationAwareBeanPostProcessors继承而来
  16. @Override
  17. public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
  18. // 寻找注入的元数据,其中它有注解扫描,和类属性信息的填充
  19. InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  20. try {
  21. // 把数据注入到当前的bean,由于需要分析的过程太多就略过怎么实现的
  22. metadata.inject(bean, beanName, pvs);
  23. }
  24. catch (BeanCreationException ex) {
  25. throw ex;
  26. }
  27. catch (Throwable ex) {
  28. throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
  29. }
  30. return pvs;
  31. }

BeanPostProcessor 的职责是在 bean 初始化后进行实例的更改,所以我们在普通 bean 实例化的时候就可以看见它的身影 AbstractAutowireCapableBeanFactory 中的 populateBean 就是给 bean 属性填充值,同样我们省略大部分代码:

  1. protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2. // true 因为我们有InstantiationAwareBeanPostProcessors的实现子类
  3. boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  4. boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
  5. PropertyDescriptor[] filteredPds = null;
  6. if (hasInstAwareBpps) {
  7. if (pvs == null) {
  8. pvs = mbd.getPropertyValues();
  9. }
  10. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  11. // 主要方法
  12. PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  13. if (pvsToUse == null) {
  14. if (filteredPds == null) {
  15. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  16. }
  17. pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  18. if (pvsToUse == null) {
  19. return;
  20. }
  21. }
  22. pvs = pvsToUse;
  23. }
  24. }
  25. }

至此当前的 bean 就实现了@Autowired 的字段注入,整个过程看似简单,但却有诸多细节。