前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >万能的BeanPostProcessor是如何让spring无限扩展的?

万能的BeanPostProcessor是如何让spring无限扩展的?

作者头像
苏三说技术
发布2020-10-15 14:42:49
2.2K0
发布2020-10-15 14:42:49
举报
文章被收录于专栏:苏三说技术

关注“苏三说技术”,回复:开发手册、时间管理 有惊喜。

很多朋友一提到spring,首先想到的肯定是IOC(控制反转)和 AOP (面向切面编程),没错,这两个是spring的核心功能。但是什么技术让spring拥有如此强大的扩展能力,

答案是:BeanFactoryPostProcessor和BeanPostProcessor 。

如果你使用过placeholder的方式定义和使用参数的话,它的底层是通过PropertyPlaceholderConfigurer类实现的,该类的子类

PropertyResourceConfigurer实现了BeanFactoryPostProcessor接口。

如果你使用过@Configuration注解定义过bean,它的底层是通过

ConfigurationClassPostProcessor类实现的,该类的实现了

BeanDefinitionRegistryPostProcessor接口,该接口继承于

BeanFactoryPostProcessor接口。

如果你使用过自定义类型转换器,它的底层是通过CustomEditorConfigurer类实现的,该类实现了BeanFactoryPostProcessor接口。

如果你自定义过scope(作用域),它的底层是通过CustomScopeConfigurer类实现的,该类实现了BeanFactoryPostProcessor接口。

如果你使用过AOP,这个大家应该都使用过,它的底层是通过AbstractAutoProxyCreator类实现的,该类实现了

SmartInstantiationAwareBeanPostProcessor接口,该接口的子接口InstantiationAwareBeanPostProcessor实现了BeanPostProcessor接口。

如果你使用过@Autowired注解,这个注解很多人可能天天在用。它的底层是通过

AutowiredAnnotationBeanPostProcessor类实现的,该类最终实现了BeanPostProcessor接口。

如果你使用过@PostConstruct(初始化)和@PreDestroy(释放资源)注解,它的底层是通过

InitDestroyAnnotationBeanPostProcessor类实现的,该类最终实现了BeanPostProcessor接口。

如果你通过实现ApplicationContextAware接口,拿到过ApplicationContext对象的实例,它的底层是通过

ApplicationContextAwareProcessor类赋值的,该类实现了BeanPostProcessor接口。

等等。。。

哈哈哈,有没有刷新三观的感觉,spring中有如此多的地方使用了

BeanFactoryPostProcessor和BeanPostProcessor ,但是我们却不一定知道,实在惭愧。


下面我从如下几方面介绍一下

  • 什么是BeanFactoryPostProcessor
  • 如何自定义BeanFactoryPostProcessor
  • 什么是BeanPostProcessor
  • 如何自定义BeanPostProcessor
  • BeanFactoryPostProcessor和BeanPostProcessor的区别
  • spring内部的调用流程
  • 总结

1.什么是BeanFactoryPostProcessor

BeanFactoryPostProcessor是一个接口,

它只有一个方法:postProcessBeanFactory,用它可以在bean实例化前修改BeanDefinition的相关信息。但是千万不要进行bean实例化,这么做可能会导致bean被提前实例化,会破坏容器造成预估不到的副作用。

2.如何自定义BeanFactoryPostProcessor

代码语言:javascript
复制
@Component
public class CustomizeBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        AbstractBeanDefinition abstractBeanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("userService");
        MutablePropertyValues pv =  abstractBeanDefinition.getPropertyValues();
        pv.addPropertyValue("name", "sue");
        abstractBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
    }
}

只用实现BeanFactoryPostProcessor接口,重写postProcessBeanFactory方法即可。可以在该方法中修改BeanDefinition中的属性 和 scope。

3.什么是BeanPostProcessor

BeanPostProcessor也是一个接口,

代码语言:javascript
复制
public interface BeanPostProcessor {

  @Nullable
  default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }

  @Nullable
  default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }

}

它有两个方法:postProcessBeforeInitialization 和 postProcessAfterInitialization,其中postProcessBeforeInitialization方法是在初始化实例之前调用的,postProcessAfterInitialization是在初始化实例之后调用的。这两个方法可以直接使用实例化好的bean,可以对bean进行转换或者属性复制等操作。

4.如何自定义BeanPostProcessor

代码语言:javascript
复制
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(final Object bean, String beanName) throws BeansException {
    AccessControlContext acc = null;

    if (System.getSecurityManager() != null &&
        (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
      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) {
    if (bean instanceof Aware) {
      if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
      }
      if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
      }
      if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
      }
      if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
      }
      if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
      }
      if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
      }
    }
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) {
    return bean;
  }

}

只用实现BeanPostProcessor接口,重写postProcessBeforeInitialization或postProcessAfterInitialization方法即可。可以在postProcessBeforeInitialization方法中setXXX一些参数,某个业务类如果实现XXXAware接口时,就可以拿到这些参数,做进一步的逻辑处理了。

5.BeanFactoryPostProcessor和BeanPostProcessor的区别

BeanFactoryPostProcessor是在spring容器实例化bean之前读取bean的定义(配置元数据),可以获取到BeanDefinition,并可以修改它。

BeanPostProcessor是在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。初始化方法包括以下两种:

1、实现InitializingBean接口的bean,对应方法为afterPropertiesSet

2、xml定义中,通过init-method设置的方法

6.spring内部的调用流程

让我们一起先看看AbstractApplicationContext类的refresh方法

代码语言:javascript
复制
  @Override
  public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      // 容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性
      prepareRefresh();

      // 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器
      prepareBeanFactory(beanFactory);

      try {
        // 允许在子类中对beanFactory进行扩展处理
        postProcessBeanFactory(beanFactory);

        // 调用BeanFactoryPostProcessor
        invokeBeanFactoryPostProcessors(beanFactory);

        // 注册BeanPostProcessor
        registerBeanPostProcessors(beanFactory);

        // 初始化国际化工具类MessageSource
        initMessageSource();

        // 初始化事件广播器
        initApplicationEventMulticaster();

        // 子类实现在容器刷新的时候可以自定义逻辑
        onRefresh();

        // 注册监听器
        registerListeners();

        // 实例化所有剩余的(非懒加载)单例,并且调用BeanPostProcessor
        finishBeanFactoryInitialization(beanFactory);

        // 初始化上下文的生命周期处理器
        finishRefresh();
      }

      catch (BeansException ex) {
        if (logger.isWarnEnabled()) {
          logger.warn("Exception encountered during context initialization - " +
              "cancelling refresh attempt: " + ex);
        }

        // Destroy already created singletons to avoid dangling resources.
        destroyBeans();

        // Reset 'active' flag.
        cancelRefresh(ex);

        // Propagate exception to caller.
        throw ex;
      }

      finally {
        // Reset common introspection caches in Spring's core, since we
        // might not ever need metadata for singleton beans anymore...
        resetCommonCaches();
      }
    }
  }

首先,obtainFreshBeanFactory方法会读取配置文件,为bean生成BeanDefinition对象,这个方法非常复杂,在这里我只是抛砖引玉就不过多介绍了,后面再机会写一个专题。

接下来,invokeBeanFactoryPostProcessors方法会注册并调用BeanFactoryPostProcessor。我们重点看看这个方法。

真正核心的是PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法:

代码语言:javascript
复制
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();

    //如果是BeanDefinitionRegistry类型
    //beanFactory为DefaultListableBeanFactory,
    // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
    if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      //存放BeanFactoryPostProcessor对象
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
       //存放BeanDefinitionRegistryPostProcessor对象
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      //首先处理入参中的beanFactoryPostProcessors
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
        //如果是BeanDefinitionRegistryPostProcessor类型
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
          BeanDefinitionRegistryPostProcessor registryProcessor =
              (BeanDefinitionRegistryPostProcessor) postProcessor;
          registryProcessor.postProcessBeanDefinitionRegistry(registry);
          registryProcessors.add(registryProcessor);
        }
        else {
          regularPostProcessors.add(postProcessor);
        }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      //首先调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
      String[] postProcessorNames =
          beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
          processedBeans.add(ppName);
        }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // 接下来调用实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
        if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
          processedBeans.add(ppName);
        }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // 最后调用其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
      boolean reiterate = true;
      while (reiterate) {
        reiterate = false;
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
          if (!processedBeans.contains(ppName)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
            reiterate = true;
          }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();
      }

      //调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      //调用BeanFactoryPostProcessor的postProcessBeanFactory方法
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
      // 如果不是BeanDefinitionRegistry类型,则直接调用postProcessBeanFactory方法
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }


    // 找到所有实现了BeanFactoryPostProcessor接口的bean名称
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
        // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
      }
      else {
        nonOrderedPostProcessorNames.add(ppName);
      }
    }

    //首先调用实现了PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 接下来调用实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    //最后调用其他的BeanFactoryPostProcessor的postProcessBeanFactory方法
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
  }

其中,invokeBeanFactoryPostProcessors方法的逻辑其实非常简单,就是循环调用postProcessBeanFactory方法

代码语言:javascript
复制
  private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

      for (BeanFactoryPostProcessor postProcessor : postProcessors) {
           postProcessor.postProcessBeanFactory(beanFactory);
     }
  }

上面invokeBeanFactoryPostProcessors方法的代码看起来很长,逻辑其实很简单。

  1. 首先判断beanFactory是否为BeanDefinitionRegistry类型,先处理入参中的beanFactoryPostProcessors,如果是则判断如果是BeanDefinitionRegistryPostProcessor类型的调用postProcessBeanDefinitionRegistry方法。收集参数中的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor对象。
  2. 再处理实现了BeanDefinitionRegistryPostProcessor接口的对象,先后调用实现了PriorityOrdered接口、实现了Ordered接口 和 其他没有顺序的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。
  3. 接下来,调用从参数中收集到的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor对象的postProcessBeanFactory方法。
  4. 如果beanFactory不是BeanDefinitionRegistry类型,则直接调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法。
  5. 最后处理实现了BeanPostProcessor接口的对象,同样调用实现了PriorityOrdered接口、实现了Ordered接口 和 其他没有顺序的BeanPostProcessor的postProcessBeanFactory方法。

也许,你可能会问题,为什么BeanDefinitionRegistryPostProcessor也有postProcessBeanFactory方法?

从图中可以看到,BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,它是一种特殊的BeanFactoryPostProcessor。

那么问题又来了,BeanDefinitionRegistryPostProcessor存在的意义是什么呢?

可以用它动态注册Bean到Spring容器。

下面给大家演示一个例子

代码语言:javascript
复制
public class ConfigPropertySourcesProcessor extends PropertySourcesProcessor implements BeanDefinitionRegistryPostProcessor {
    public ConfigPropertySourcesProcessor() {
    }

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        Map<String, Object> propertySourcesPlaceholderPropertyValues = new HashMap();
        propertySourcesPlaceholderPropertyValues.put("order", 0);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(), PropertySourcesPlaceholderConfigurer.class, propertySourcesPlaceholderPropertyValues);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(), ApolloAnnotationProcessor.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(), SpringValueProcessor.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloJsonValueProcessor.class.getName(), ApolloJsonValueProcessor.class);
        this.processSpringValueDefinition(registry);
    }

    private void processSpringValueDefinition(BeanDefinitionRegistry registry) {
        SpringValueDefinitionProcessor springValueDefinitionProcessor = new SpringValueDefinitionProcessor();
        springValueDefinitionProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}
代码语言:javascript
复制
public class BeanRegistrationUtil {
    public BeanRegistrationUtil() {
    }

    public static boolean registerBeanDefinitionIfNotExists(BeanDefinitionRegistry registry, String beanName, Class<?> beanClass) {
        return registerBeanDefinitionIfNotExists(registry, beanName, beanClass, (Map)null);
    }

    public static boolean registerBeanDefinitionIfNotExists(BeanDefinitionRegistry registry, String beanName, Class<?> beanClass, Map<String, Object> extraPropertyValues) {
        if (registry.containsBeanDefinition(beanName)) {
            return false;
        } else {
            String[] candidates = registry.getBeanDefinitionNames();
            String[] arr$ = candidates;
            int len$ = candidates.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                String candidate = arr$[i$];
                BeanDefinition beanDefinition = registry.getBeanDefinition(candidate);
                if (Objects.equals(beanDefinition.getBeanClassName(), beanClass.getName())) {
                    return false;
                }
            }

            BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(beanClass).getBeanDefinition();
            if (extraPropertyValues != null) {
                Iterator i$ = extraPropertyValues.entrySet().iterator();

                while(i$.hasNext()) {
                    Entry<String, Object> entry = (Entry)i$.next();
                    beanDefinition.getPropertyValues().add((String)entry.getKey(), entry.getValue());
                }
            }

            registry.registerBeanDefinition(beanName, beanDefinition);
            return true;
        }
    }
}

使用BeanDefinitionRegistryPostProcessor可以动态的注入BeanDefinition对象。

接下来,我们再回到refresh方法,看看registerBeanPostProcessors方法。

代码语言:javascript
复制
  protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
  }
代码语言:javascript
复制
public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    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;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
        }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
      }
      else {
        nonOrderedPostProcessorNames.add(ppName);
      }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
      }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
      }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    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).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  }

它会将实现了PriorityOrdered接口、实现了Ordered接口 和 其他没有顺序的BeanPostProcessor收集到beanPostProcessors集合中。

然后在调用applicationContext.getBean("name")方法时

,在initializeBean(初始化bean)方法中调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。

spring中创建bean的三个关键的流程是:

创建bean实例、依赖注入 和 初始化bean,分别对应三个方法:createBeanInstance、populateBean 和 initializeBean。

接下来重点看看initializeBean方法:

代码语言:javascript
复制
  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);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
      //调用BeanPostProcessor的postProcessBeforeInitialization方法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
      invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          (mbd != null ? mbd.getResourceDescription() : null),
          beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
      //调用BeanPostProcessor的postProcessAfterInitialization方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
  }
代码语言:javascript
复制
  @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;
  }
代码语言:javascript
复制
  @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;
  }

7.总结

BeanFactoryPostProcessor和BeanPostProcessor都是接口。

BeanFactoryPostProcessor又分为:BeanDefinitionRegistryPostProcessor普通BeanFactoryPostProcessor

BeanDefinitionRegistryPostProcessor主要用于动态注册beanDefinition对象到spring容器。

普通BeanFactoryPostProcessor主要用在spring容器实例化bean之前读取bean的定义(配置元数据),可以获取到BeanDefinition,并可以修改它。

BeanPostProcessor主要用于spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 苏三说技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档