SpringBoot 配置文件加载源码学习探究

SpringBoot 在项目根路径添加 config 配置,有些项目运行的时候配置不起作用,本文对SpringBoot源码配置文件加载进行解读学习探究

SpringBoot 集成 NacosRegister 源码启动顺序

  1. @SpringBootApplication 注解 main 函数执行
  2. SpringBootApp() 构造函数
    • getSpringFactoriesInstances(BootstrapRegistryInitializer.class) 加载

      • SpringFactoriesLoader.loadFactoryNames(type, classLoader)

      • SpringFactoriesLoader.loadSpringFactories

        • Enumeration urls = classLoader.getResources(‘META-INF/spring.factories’)
        • urls.foreach
          • jar:file:/C:/Users/SCWANG/.m2/repository/io/springboot/nacos/nacos-config/2.2.4/nacos-config-2.2.4.jar!/META-INF/spring.factories

          • Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url))

            • #fillProperties(new Properties(), resource)
              • resource.getInputStream()
                • URLConnection con = this.url.openConnection()
                • return con.getInputStream();
          • properties:

            • org.springframework.context.ApplicationContextInitializer ->
              • com.alibaba.nacos.config.server.utils.PropertyUtil
          • jar:file:/C:/Users/SCWANG/.m2/repository/io/springboot/nacos/nacos-core/2.2.4/nacos-core-2.2.4.jar!/META-INF/spring.factories

          • properties:

            • org.springframework.boot.SpringApplicationRunListener ->

              • com.alibaba.nacos.core.code.SpringApplicationRunListener
            • org.springframework.context.ApplicationListener ->

              • com.alibaba.nacos.core.code.StandaloneProfileApplicationListener
          • jar:file:/C:/Users/SCWANG/.m2/repository/io/springboot/nacos/nacos-sys/2.2.4/nacos-sys-2.2.4.jar!/META-INF/spring.factories

          • properties:

            • org.springframework.context.ApplicationContextInitializer ->
              • com.alibaba.nacos.sys.utils.ApplicationUtils
          • … 后续循环看下面章节

    • BootstrapRegistryInitializer.class:

      • 加载到:
        • org.springframework.cloud.bootstrap.RefreshBootstrapRegistryInitializer
        • org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper
      • #createSpringFactoriesInstances 创建实例
        • 0 = {RefreshBootstrapRegistryInitializer@1822}
        • 1 = {TextEncryptorConfigBootstrapper@1823}
    • getSpringFactoriesInstances(ApplicationContextInitializer.class) 加载

    • ApplicationContextInitializer.class

    • 赋值到 bootstrapRegistryInitializers 字段

    • META-INF/spring.factories

  3. SpringBootApp#run 函数执行
    • 执行 prepareEnvironment 准备变量
      • #getOrCreateEnvironment
      • #applicationContextFactory.createEnvironment(this.webApplicationType)
        • getFromSpringFactories 读取
    • 根据 webApplicationType 和 applicationContextFactory 创建环境对象
    • SpringBootApp.listeners 触发 environmentPrepared 监听
      • com.alibaba.nacos.core.code.SpringApplicationRunListener [nacos 监听到事件]

      • EventPublishingRunListener 监听到 environmentPrepared
        • 使用 initialMulticaster 多播 ApplicationEnvironmentPreparedEvent 事件
      • EnvironmentPostProcessorApplicationListener 接收到多播事件
        • 多个 EnvironmentPostProcessor 循环处理事件
        • ConfigDataEnvironmentPostProcessor 轮到处理事件
          • ConfigDataEnvironmentContributors 和 Binder 一顿循环绕来绕去
          • 然后 ConfigDataImporter 处理配置文件的 resolve
          • 最终 StandardConfigDataLocationResolver resolve
            • optional:file:./;optional:file:./config/;optional:file:./config/*/
            • 然后 #getReferencesForDirectory 函数拼接 目录和文件
              • configNames 字段存储了配置文件的名称
                • [“bootstrap”]
                • [“application”]
            • propertySourceLoaders 字段存储了 两种配置加载器
              • YamlPropertySourceLoader (properties,xml)
              • PropertiesPropertySourceLoader (yml,yaml)
              • file:./application.yaml
              • file:./application.yml
              • file:./application.xml
              • file:./application.properties
              • file:./config/application.yaml
              • file:./config/application.yml
              • file:./config/application.xml
              • file:./config/application.properties
              • file:./config/*/application.yaml
              • file:./config/*/application.yml
              • file:./config/*/application.xml
              • file:./config/*/application.properties
            • 最终 #resolve(StandardConfigDataReference reference) 判断文件存在
      • 返回 ApplicationServletEnvironment 对象
    • SpringBootApp 初始化结束

spring.factories 循环读取完整版

  • jar:file:/C:/Users/SCWANG/.m2/repository/io/springboot/nacos/nacos-config/2.2.4/nacos-config-2.2.4.jar!/META-INF/spring.factories

  • Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url))

    • #fillProperties(new Properties(), resource)
      • resource.getInputStream()
        • URLConnection con = this.url.openConnection()
        • return con.getInputStream();
  • properties:

    • org.springframework.context.ApplicationContextInitializer ->
      • com.alibaba.nacos.config.server.utils.PropertyUtil
  • jar:file:/C:/Users/SCWANG/.m2/repository/io/springboot/nacos/nacos-core/2.2.4/nacos-core-2.2.4.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.boot.SpringApplicationRunListener ->

      • com.alibaba.nacos.core.code.SpringApplicationRunListener
    • org.springframework.context.ApplicationListener ->

      • com.alibaba.nacos.core.code.StandaloneProfileApplicationListener
  • jar:file:/C:/Users/SCWANG/.m2/repository/io/springboot/nacos/nacos-sys/2.2.4/nacos-sys-2.2.4.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.context.ApplicationContextInitializer ->
      • com.alibaba.nacos.sys.utils.ApplicationUtils
  • jar:file:/C:/Users/SCWANG/.m2/repository/org/springframework/spring-beans/5.3.33/spring-beans-5.3.33.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.beans.BeanInfoFactory ->
      • org.springframework.beans.ExtendedBeanInfoFactory
  • jar:file:/C:/Users/SCWANG/.m2/repository/org/springframework/cloud/spring-cloud-commons/3.1.7/spring-cloud-commons-3.1.7.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.boot.diagnostics.FailureAnalyzer” ->
      • org.springframework.cloud.configuration.CompatibilityNotMetFailureAnalyzer”
    • pringframework.boot.env.EnvironmentPostProcessor” ->
      • org.springframework.cloud.client.HostInfoEnvironmentPostProcessor”
    • pringframework.boot.autoconfigure.EnableAutoConfiguration” ->
      • org.springframework.cloud.client.CommonsClientAutoConfiguration
      • org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration
      • org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration
      • org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration
      • org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration
      • org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration
      • org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration
      • org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration
      • org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration
      • org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration
      • org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration
      • org.springframework.cloud.c”
  • jar:file:/C:/Users/SCWANG/.m2/repository/org/springframework/cloud/spring-cloud-context/3.1.7/spring-cloud-context-3.1.7.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.boot.BootstrapRegistryInitializer” ->
      • org.springframework.cloud.bootstrap.RefreshBootstrapRegistryInitializer
      • org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper”
    • pringframework.boot.env.EnvironmentPostProcessor” ->
      • org.springframework.cloud.bootstrap.encrypt.DecryptEnvironmentPostProcessor
      • org.springframework.cloud.util.random.CachedRandomPropertySourceEnvironmentPostProcessor”
    • pringframework.cloud.bootstrap.BootstrapConfiguration” ->
      • org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration
      • org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration
      • org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration
      • org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration”
    • pringframework.context.ApplicationListener” ->
      • org.springframework.cloud.bootstrap.BootstrapApplicationListener
      • org.springframework.cloud.bootstrap.LoggingSystemShutdownListener
      • org.springframework.cloud.context.restart.RestartListener”
    • pringframework.boot.autoconfigure.EnableAutoConfiguration” ->
      • org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration
      • org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration
      • org.springframework.cloud.autoconfigure.RefreshAutoConfiguration
      • org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration
      • org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration”
  • jar:file:/C:/Users/SCWANG/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.7.18/spring-boot-autoconfigure-2.7.18.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector” ->
      • org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDatabaseInitializerDetector”
    • org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider” ->
      • org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider
      • org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider
      • org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider
      • org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider
      • org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider”
    • org.springframework.boot.env.EnvironmentPostProcessor” ->
      • org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor”
    • org.springframework.context.ApplicationContextInitializer” ->
      • org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
      • org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener”
    • org.springframework.boot.diagnostics.FailureAnalyzer” ->
      • org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer
      • org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer
      • org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer
      • org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer
      • org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer
      • org.springframework.boot.autoconfigure.jooq.NoDslContextBeanFailureAnalyzer
      • org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer
      • org.springframework.boot.autoconfigure.r2dbc.MissingR2dbcPoolDependencyFailureAnalyzer
      • org.springframework.boot.autoconfigure.r2dbc.MultipleConnectionPoolConfigurationsFailureAnalyzer
      • org.springframework.boot.autoconfigure.r2dbc.NoConnectionFactoryBeanFailureAnalyzer
      • org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer”
    • org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector” ->
      • org.springframework.boot.autoconfigure.batch.JobRepositoryDependsOnDatabaseInitializationDetector
      • org.springframework.boot.autoconfigure.quartz.SchedulerDependsOnDatabaseInitializationDetector
      • org.springframework.boot.autoconfigure.session.JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector”
    • org.springframework.boot.autoconfigure.AutoConfigurationImportListener” ->
      • org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener”
    • org.springframework.context.ApplicationListener” ->
      • org.springframework.boot.autoconfigure.BackgroundPreinitializer”
    • org.springframework.boot.autoconfigure.AutoConfigurationImportFilter” ->
      • org.springframework.boot.autoconfigure.condition.OnBeanCondition
      • org.springframework.boot.autoconfigure.condition.OnClassCondition
      • org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition”
  • jar:file:/C:/Users/SCWANG/.m2/repository/org/springframework/boot/spring-boot/2.7.18/spring-boot-2.7.18.jar!/META-INF/spring.factories

  • properties:

    • org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector ->
      • org.springframework.boot.flyway.FlywayDatabaseInitializerDetector
      • org.springframework.boot.jdbc.AbstractDataSourceInitializerDatabaseInitializerDetector
      • org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializerDetector
      • org.springframework.boot.liquibase.LiquibaseDatabaseInitializerDetector
      • org.springframework.boot.orm.jpa.JpaDatabaseInitializerDetector
      • org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializerDetector
    • org.springframework.boot.env.PropertySourceLoader ->
      • org.springframework.boot.env.PropertiesPropertySourceLoader
      • org.springframework.boot.env.YamlPropertySourceLoader
    • org.springframework.boot.logging.LoggingSystemFactory ->
      • org.springframework.boot.logging.logback.LogbackLoggingSystem.Factory
      • org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory
      • org.springframework.boot.logging.java.JavaLoggingSystem.Factory
    • org.springframework.boot.context.config.ConfigDataLoader ->
      • org.springframework.boot.context.config.ConfigTreeConfigDataLoader
      • org.springframework.boot.context.config.StandardConfigDataLoader
    • org.springframework.boot.SpringApplicationRunListener ->
      • org.springframework.boot.context.event.EventPublishingRunListener
    • org.springframework.boot.diagnostics.FailureAnalysisReporter ->
      • org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter”
    • org.springframework.boot.env.EnvironmentPostProcessor ->
      • org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
      • org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor
      • org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor
      • org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
      • org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
      • org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor”
    • org.springframework.boot.SpringBootExceptionReporter ->
      • org.springframework.boot.diagnostics.FailureAnalyzers”
    • org.springframework.context.ApplicationContextInitializer ->
      • org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
      • org.springframework.boot.context.ContextIdApplicationContextInitializer
      • org.springframework.boot.context.config.DelegatingApplicationContextInitializer
      • org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer
      • org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer”
    • org.springframework.boot.diagnostics.FailureAnalyzer ->
      • org.springframework.boot.context.config.ConfigDataNotFoundFailureAnalyzer
      • org.springframework.boot.context.properties.IncompatibleConfigurationFailureAnalyzer
      • org.springframework.boot.context.properties.NotConstructorBoundInjectionFailureAnalyzer
      • 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.MutuallyExclusiveConfigurationPropertiesFailureAnalyzer
      • org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer
      • org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer
    • org.springframework.boot.ApplicationContextFactory ->
      • org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext.Factory
      • org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext.Factory”
    • org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector ->
      • org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector
      • org.springframework.boot.jdbc.SpringJdbcDependsOnDatabaseInitializationDetector
      • org.springframework.boot.jooq.JooqDependsOnDatabaseInitializationDetector
      • org.springframework.boot.orm.jpa.JpaDependsOnDatabaseInitializationDetector”
    • org.springframework.boot.context.config.ConfigDataLocationResolver ->
      • org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver
      • org.springframework.boot.context.config.StandardConfigDataLocationResolver”
    • org.springframework.context.ApplicationListener ->
      • 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.DelegatingApplicationListener
      • org.springframework.boot.context.logging.LoggingApplicationListener
      • org.springframework.boot.env.EnvironmentPostProcessorApplicationListener”