zoukankan      html  css  js  c++  java
  • SpringBoot启动及配置文件加载原理分析

    大家好,这篇文章将跟大家一起来分析一下SpringBoot启动及配置文件加载原理分析。废话不多说,直接开干吧。。。。。

    一、看前必备技能

            Spring SPI机制,类似像Java的ServiceLoader、或者Dubbo的ExtensionLoader。

            因为下面讲到的Spring的Listener加载机制会涉及到SPI技术(当然这里Spring的监听事件不清楚的小伙伴可以先去做个了解)。

    二、SpringBoot初始化启动原理分析

            1、由启动主动函数入口切入分析

            

           2、由启动源码分析 SpringApplication.run(DszMasterApplication.class, args);这里面有两个内容,第一初始化SpringApplication,第二是初始化SpringApplication后开始真正运行run方法。

          如下图:

                   

            3、这里先看SpringApplication的初始化,其实里面最重要的就是SpringBoot自动装载机制,像监听器Listeners初始化,还有什么InitiaLizers。当然还有很多其他初始化任务。这里我们来重点看一下Listener监听注册的初始化。

                由上面截图new SpringApplication()构造方法进去可以看到

                    

                  这里我们重点看下setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));,由getSpringFactoriesInstances进去可以看到

                   

                 这里的names就是收集了初始化后的ApplicationListener的所有实现的监听器,具体有10个如下图

                  

                  接下来给大家再往下具体分析这个监听器是如何被初始化的,进入SpringFactoriesLoader.loadFactoryNames(type, classLoader)中如下

                  

                    然后再进入loadSpringFactories方法,如下

                           private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {

                //这里将会最终存放所有初始化后的监听器
    MultiValueMap<String, String> result = cache.get(classLoader);
    if (result != null) {
    return result;
    }

    try {
    Enumeration<URL> urls = (classLoader != null ?
    //下面的的 FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”,这个地方往下就会涉及到Spring的自动装配SPI机制了
                 classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
    result = new LinkedMultiValueMap<>();
    while (urls.hasMoreElements()) {
    URL url = urls.nextElement();
    UrlResource resource = new UrlResource(url);
    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
    for (Map.Entry<?, ?> entry : properties.entrySet()) {
    String factoryClassName = ((String) entry.getKey()).trim();
    for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
    result.add(factoryClassName, factoryName.trim());
    }
    }
    }
    //这里将会吧所有的初始化的监听对象放入缓存中
    cache.put(classLoader, result);
    return result;
    }
    catch (IOException ex) {
    throw new IllegalArgumentException("Unable to load factories from location [" +
    FACTORIES_RESOURCE_LOCATION + "]", ex);
    }
    }

          那么上面的spring.factories文件是在哪里的呢,通过调试得知如下图

                            

                          由此可知我们可以按照这个path找出这个文件

                              

                             现在让我们来看下这个文件到底张什么样的,我们打开这个文章一起来看下

                             

                # PropertySource Loaders
    org.springframework.boot.env.PropertySourceLoader=
    org.springframework.boot.env.PropertiesPropertySourceLoader,
    org.springframework.boot.env.YamlPropertySourceLoader

    # Run Listeners
    org.springframework.boot.SpringApplicationRunListener=
    org.springframework.boot.context.event.EventPublishingRunListener

    # Error Reporters
    org.springframework.boot.SpringBootExceptionReporter=
    org.springframework.boot.diagnostics.FailureAnalyzers

    # Application Context Initializers
    org.springframework.context.ApplicationContextInitializer=
    org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
    org.springframework.boot.context.ContextIdApplicationContextInitializer,
    org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
    org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

    # Application Listeners
    org.springframework.context.ApplicationListener=
    //以下都是ApplicatinListener的实现类,这些类都将会在上面
    org.springframework.boot.ClearCachesApplicationListener,
    org.springframework.boot.builder.ParentContextCloserApplicationListener,
    org.springframework.boot.context.FileEncodingApplicationListener,
    org.springframework.boot.context.config.AnsiOutputApplicationListener,
    org.springframework.boot.context.config.ConfigFileApplicationListener,
    org.springframework.boot.context.config.DelegatingApplicationListener,
    org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,
    org.springframework.boot.context.logging.LoggingApplicationListener,
    org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

    # Environment Post Processors
    org.springframework.boot.env.EnvironmentPostProcessor=
    org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
    org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,
    org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor

    # Failure Analyzers
    org.springframework.boot.diagnostics.FailureAnalyzer=
    org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,
    org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer

    # FailureAnalysisReporters
    org.springframework.boot.diagnostics.FailureAnalysisReporter=
    org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

             由上内容得知,spring.factories定义了一系列springboot启动需要杯加载初始化的类,通过如下调试得知

                                

                               这里我们来具体看下ApplictionListener加载的那些类,因为这些跟我们接下来要讲的CnfigFileListener会有关系。其实很简单,在MultiValueMap<String, String> result = cache.get(classLoader);的结果集别刻意看出,因为最终初始化的

                              所有对象都将add到这个result中去。看下结果图如下: 

                               

                               在这里边可以看到所有的Listener初始化的结果。

                                今晚由于时间比较晚,还有run部分和配置文件加载原理就留给下次给大家补上。由于最近刚写博客,样式排版上没有太多精力,后期会给大家慢慢优化回来。

                               今晚总结时序图给大家回顾一下吧:

                                

                               具体细节大家按照上面讲的回顾就好了。

                          

                             

     

                               

        

                     

  • 相关阅读:
    吞吐量(TPS)、QPS、并发数、响应时间(RT)
    吞吐量(TPS)、QPS、并发数、响应时间(RT)
    ubuntu 14.04安装pycharm 社区版
    ubuntu 14.04安装pycharm 社区版
    卷积神经网络(4)----目标检测
    卷积神经网络(4)----目标检测
    卷积神经网络(4)----目标检测
    如何搭建自己CDN服务器
    flask
    s16 计算机网络基础
  • 原文地址:https://www.cnblogs.com/dszazhy/p/11513012.html
Copyright © 2011-2022 走看看