springboot源码解析(四)

之前通过debug的方式详细了解了SpringBoot启动的配置文件加载和容器初始化的相关的工作。但是对于核心的refresh()没有进行解析。而spring对于SpringApplication的准备工作的最终处理都是在refresh中执行的。所以深入理解refresh是理解spring的基础。而我们之前的学习为我们理解refresh打下了坚实的基础。甚至我们也猜测了后置处理器的工作方式,所以个人感觉理解refresh不会遇到特别难的地方。这里写一点个人学习的小经验。

首先我们认为兴趣是最好的老师这句话是正确的。可是对于一个人来说,他对所谓的兴趣并没有兴趣。那么问题就变成了有教无类和因人而异的两种教育教育理念。话虽说的很有道理,貌似都是极大的发挥了个人的天性并冒失实现了个人的价值。毫无疑问,如果按这种指导思想每个人都可以很伟大。但是现实在很大程度并不是这样,所谓人无完人,你所在乎的在别人看来并非如此。所以一切都是听天由命,不要被新闻的惨剧而担忧。不因自己的幸运而庆幸。所以真确的价值观是面对选择的根本执念。明白什么是核心什么是外表修饰。所以我的观点是:有教无类+因人而异。那么如何判断这两者的边界?你总不能做个两面派然后来回跳吧。其实这两者是有明确的边界的。我个人觉得有教无类是就是正确观的教育。因人而异则是个人优势的放大。很多人没有正确的价值观,无限放到的个人的优势的过程其实是没有什么意义。毕竟人还是要对主流思潮保持敬畏。那么在上边说的正确观的教育中如何培训那种兴趣?因人而异的特质是不需要刻意的引导的。所以问题的核心是如何培养那种这种关乎核心甚至决定一切的核心力量的兴趣上。第一点,要经常反思自己。反思的意义深远而悠长。第二,对于面对的挑战和问题,勇于提出自己的观点,这种观点建立在自己已知的是事情上,并尝试基于此解释现有的困难。第三,查看现有的资料,通过不断对比两种想法的差距,不断反思和自我鼓励。从而使得灵魂更上一个层次。

一不小心说了那么多话,其实我觉得相比技术来说,那些看似没有用的话,其实才是最有用的,当然说出来并不见的有用。正如一个人只能挣他认知范围内的钱一般,一时的思绪万千和急性的死记硬背都毫无意义。从某种意义上说我其实是在洗涤我自己。而观众的体验如何并非我关心的主体,虽然我希望我说的对大家有点用。

废话不说,开启我们的springBoot源码学习吧。

但是我们发现AbstractApplicationContext只是一个虚类,所以它的作用就是给子类一个限定的框架。所以看这块的代码要和子类结合起来。而这里说的的子类就是我们在SpringApplication中创建的content,也就是AnnotationConfigServletWebServerApplicationContext

//刷新容器之前做一些准备工作
  protected void prepareRefresh() {
    // 开始的时间 
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    if (logger.isDebugEnabled()) {
      if (logger.isTraceEnabled()) {
        logger.trace("Refreshing " + this);
      }
      else {
        logger.debug("Refreshing " + getDisplayName());
      }
    }
    // Initialize any placeholder property sources in the context environment.
    initPropertySources();
    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    getEnvironment().validateRequiredProperties();
    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
      // Reset local application listeners to pre-refresh state.
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
    }


    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
  }

这里我们发现abstrctApplicationContent是我们content的父类,通过idea定位发现initPropertySources其实是在GenericWebApplicationContext类中实现的。

通过定位debug,发现这里就是对一些属性的赋值

    protected void initPropertySources() {
        ConfigurableEnvironment env = this.getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
            ((ConfigurableWebEnvironment)env).initPropertySources(this.servletContext, (ServletConfig)null);
        }
    }
    //这里的source就是我们解析的那6个配置文件
    //所以这块显然就是为了将配置文件的属性值来替换这里的name的value了。
    //因为我们在配置文件中并没有设置这两个值,因此这里的逻辑都没有执行
    public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
        Assert.notNull(sources, "'propertySources' must not be null");
        String name = "servletContextInitParams";
        if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
            sources.replace(name, new ServletContextPropertySource(name, servletContext));
        }
        name = "servletConfigInitParams";
        if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
            sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
        }


    }

看完容器刷新的前置操作,那么我们看看obtainFreshBeanFactory();是做什么的。

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

代码很简洁,但是我们一眼就看的出来这里就是bean工厂呀,按照我们之前的解释,这里的bean工厂就是GenericWebApplicationContext类中的元素吧,那么我们看看是不是这么一回事。

  protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
  }

通过代码跟踪,这里的refreshBeanFactory调用了还是父类GenericWebApplicationContext方法。而这里的方法只是设置了容器被刷新的标志并没有做其他操作。因为之前已经创建好了bean工厂。如下图所示就是debug的结果,发现我们之前注入的bean还在该方法返回的工厂中。

那么prepareBeanFactory(beanFactory);是做什么工作的?从字面上理解就是对beanFactory做一些前置处理。

prepareBeanFactory(beanFactory);
  protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    //设置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    //设置bean的类EL表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //设置属性解析器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));


    // 给beanFactory设置一个aware,用于后期的回调。
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //设置一些需要忽略的aware接口
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);


    // BeanFactory interface not registered as resolvable type in a plain factory.
    // 给beanfactory设置一些解析
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);


    // 设置一个bean的处理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));


    // 添加一个代理解析bean
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }


    // 注册环境变量
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    //设置系统变量
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    //设置系统变量 
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }

通过上述的一些操作也就是给beanfactory设置一些必要的功能。我们继续往下看

postProcessBeanFactory(beanFactory);

这里应该就是对哪些后置处理器的调用?

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        if (this.servletContext != null) {
        //ServletContextAwareProcessor
            beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
            //在注入的时候忽略ServletContextAware接口的bean
            beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        }
//注册scopes的bean
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
     //注册环境变量的bean
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
    }

发现上述方法也并没有做过多的处理。我们继续推进。invokeBeanFactoryPostProcessors方法。

这里的getBeanFactoryPostProcessors就是获取我们SpringApplication类中读取spring.facotries类取得的初始化一些初始化类。但是这些类都有一个特点,那就是实现了initialize方法,在调用 this.applyInitializers(context)方法时就会代理产生一个后置处理器。也就是实现了BeanDefinitionRegistryPostProcessor接口的实体并注册到content中。而BeanDefinitionRegistryPostProcessor的类关系如图所示。

也就是说invokeBeanFactoryPostProcessors其实就是来调用这些后置处理器的。

  protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    //执行BeanFactoryPostProcessors
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
    //添加bean处理器器


    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
  }
  public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {


    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();
    //这里就是我们测试的demo的核心是BeanFactoryPostProcessor的子类。
    //我们测试的demo实现了BeanDefinitionRegistryPostProcessor
    //BeanDefinitionRegistry显然是被beanfactory实现d额接口
    if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();


      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
      //如果实现了BeanDefinitionRegistryPostProcessor
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
          BeanDefinitionRegistryPostProcessor registryProcessor =
              (BeanDefinitionRegistryPostProcessor) postProcessor;
           //回调一下,然后将其添加熬队列中
          registryProcessor.postProcessBeanDefinitionRegistry(registry);
          registryProcessors.add(registryProcessor);
        }
        else {
        //否则就是实现了BeanFactoryPostProcessor
          regularPostProcessors.add(postProcessor);
        }
      }
      //从容器中拿哪些已经注册的bean
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();


      // 这里通过迭代beanDefinitionMap去获取实现了BeanDefinitionRegistryPostProcessor接口的类
      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);
      //拿到beanDefinitionmap中的实现了BeanDefinitionProcesscors的接口进行调用
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

通过跟踪发现从beanDefinitionMap中获取的实现了BeanDefinitionProcesseor接口的之后一个类ConfigurationClassPostProcessor。这个类就是我们SpringApplication在context = this.createApplicationContext();方法中放到beanDefinitionmap中的。

那么这个类做了哪些工作?通过跟踪,发现该类就是用来解析的。当然解析一定会有很多关联,因此当代码运行完毕之后。代码相关的类都将注册到beanDefinitionMap中。

      //通过上边的运行,beanDefinitionMap中已经有很多用户自定义后置处理器了。这块就是处理这些的
      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();


    //获取所有的实现了接口统一进行执行
      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();
      }


      // 执行postProcessBeanFactory
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      //执行一下postProcessBeanDefinitionRegistry
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }


    else {
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }


//获取BeanFactoryPostProcessor接口的类
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    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);
      }
    }


    // 执行优先级额处理器postProcessBeanFactory
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);


    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    //执行postProcessBeanFactory
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);


    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 执行postProcessBeanFactory
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    //清空缓存
    beanFactory.clearMetadataCache();
  }

注:上述介绍均为作者的个人观点,如有不对,请指正。谢谢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值