前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot源码学习(五)

SpringBoot源码学习(五)

作者头像
写一点笔记
发布2020-09-21 15:02:32
3760
发布2020-09-21 15:02:32
举报
文章被收录于专栏:程序员备忘录程序员备忘录

在之前的学习中,我们大概的学习了springBoot的初始化。大概得流程是springApplication读取通过读取spring.factories文件中SpringBootAppliationinitlizer和springApplicationRunabaleListenner相关的接口。其中listenner伴随着SpringBoot应用启动的全过程,在每个阶段运行结束的时候都会将IOC容器传入并通知所有的listenner对象,其中ConfigFileApplicationListener在SpringApplication类中就开始对配置进行解析。而在IOC初始化结束,praperContent阶段,调用this.applyInitializers(context)的时候就将解析注解的和配置的后置处理器(实现了BeanDefinitionRegistryPostProcessor得类)全部已经注册到beanFactory中的后置处理器map中,之后通过load方法将启动类加载到beanFactory中。这一切都准备好之后,进入SpringBoot的核心启动类中。在核心类中,首先做一些准备工作包括一些容器属性通过配置文件的新值覆盖等。之后获取实现了BeanDefinitionRegistryPostProcessor接口的类进行后置处理。先进行排序,找到优先级比较高的配置解析类等。然后使用先前parperContent中applyInitializers注册的ConfigurationClassPostProcessor进行注解的解析,通过这个后置处理器的处理所有的类都注册到beanDefinitionMap中。之后通过实现了BeanDefinitionRegistryPostProcessor和Order具有排序的接口,逐个调用

postProcessBeanDefinitionRegistry进行处理。

最后逐个获取beanDefinitionMap中实现了BeanDefinitionRegistryPostProcessor接口的类再去轮询调用postProcessBeanDefinitionRegistry方法。

处理完毕之后再使用相同的方法获取实现了BeanFactoryPostProcessor接口的类,还是按照优先级、排序和beanDefinitionMap注册的顺序依次调用postProcessBeanFactory方法。其实经过上述的过程,spring的主体过程已经结束了。剩下的部分就是过去bean的一些bean后置处理。现在让我们继续之前剩下的事业吧!

首先明确一下我们今天分析的焦点,如图所示:

从字面上理解,这个registerBeanPostProcessors就是注册bean的后置处理器。我们之前BeanFactoryPostProcessors是beanFactory的后置处理器。因为他们哪些方法都是在bean工厂初始化之后调用的。那么显然这里的registr就是要将bean实例化之后的一些处理的通用类注册进来。那么必然包括从spring.factories和已经加载到beanDefinitionMap的两部分类。那么这个register就是将这两者按照顺序注册的。然后再bean实例化中逐个去调用。当然这只是我们的猜测。具体是怎么样的?让我们拭目以待。

代码语言:javascript
复制
  protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
  }
代码语言:javascript
复制
  public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory,
     AbstractApplicationContext applicationContext) {
    //获取目前存在于beanDefinitionMap中的bean后置处理器【这里有6个】
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    //将bena的后置处理器添加到beanPostProcessor中
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    //具有优先级的bean后置处理器
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    //具有顺序的bean后置处理器
    List<String> orderedPostProcessorNames = new ArrayList<>();
    //一般的bean后置处理器
    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) {
          //添加实现了MergedBeanDefinitionPostProcessor接口的后置处理器 
          internalPostProcessors.add(pp);
        }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        //具有顺序的bean后置处理器
        orderedPostProcessorNames.add(ppName);
      }
      else {
      //无序的后置处理器
        nonOrderedPostProcessorNames.add(ppName);
      }
    }

    //排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    //注册进去
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    //注册实现了Ordered接口的bean后置处理器
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      //添加到list
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
      //添加MergedBeanDefinitionPostProcessor接口的bean
        internalPostProcessors.add(pp);
      }
    }
    //排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    //注册进去
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    // 无序的bean后置处理器
    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);
    //注册MergedBeanDefinitionPostProcessor接口的
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    //在添加一个后置处理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  }

通过上述分析,registerBeanPostProcessors方法就是添加一批bean的初始化之后的后置处理器。

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

本文分享自 程序员备忘录 微信公众号,前往查看

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

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

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