美文网首页
springboot-解析yml文件

springboot-解析yml文件

作者: 无聊之园 | 来源:发表于2024-02-28 11:13 被阅读0次

    看这部分代码,这是springboot启动的run方法的代码

    public ConfigurableApplicationContext run(String... args) {
            ...
    // 获取到SpringApplicationRunListeners类
            SpringApplicationRunListeners listeners = getRunListeners(args);
    // 马上调用starting事件       
      listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            
    }
    
    private SpringApplicationRunListeners getRunListeners(String[] args) {
            Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    // 跟进去会发现也是SpringFactoriesLoader.loadFactoryNames获取的META-INFO/spring.factories里的SpringApplicationRunListener所有实现类,然后实现类对象集合作为参数再构造一个SpringApplicationRunListeners类包装一下
    //SpringApplicationRunListener的实现类只有一个 EventPublishingRunListener
        return new SpringApplicationRunListeners(logger,
                    getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
                    this.applicationStartup);
        }
    

    看EventPublishingRunListener的构造方法,就是一个事件发布的类,有事件广播器SimpleApplicationEventMulticaster,也保存了所有的ApplicationListener监听器,ApplicationListener监听器是构造SpringApplication对象的时候从META-INFO/spring.factories里获取的,然后宝SpringApplication的成员变量listeners中的。

    public EventPublishingRunListener(SpringApplication application, String[] args) {
            this.application = application;
            this.args = args;
            this.initialMulticaster = new SimpleApplicationEventMulticaster();
            for (ApplicationListener<?> listener : application.getListeners()) {
                this.initialMulticaster.addApplicationListener(listener);
            }
        }
    

    在spring-boot.jar包中的META-INFO/spring.factories里可以看到ApplicationListener有这么多实现类,这里关注EnvironmentPostProcessorApplicationListener,环境配置处理的监听器。

    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,\
    org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
    
    

    starting事件会广播所有ApplicationListener的starting事件。EnvironmentPostProcessorApplicationListener的onApplicationEvent事件监听方法不会处理ApplicationStartingEvent事件。所以不在这里。

    public void starting(ConfigurableBootstrapContext bootstrapContext) {
            this.initialMulticaster
                    .multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
        }
    
    @Override
        public void onApplicationEvent(ApplicationEvent event) {
            if (event instanceof ApplicationEnvironmentPreparedEvent) {
                onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
            }
            if (event instanceof ApplicationPreparedEvent) {
                onApplicationPreparedEvent((ApplicationPreparedEvent) event);
            }
            if (event instanceof ApplicationFailedEvent) {
                onApplicationFailedEvent((ApplicationFailedEvent) event);
            }
        }
    

    而是在这里:prepareEnvironment预处理环境方法里,触发了environmentPrepared事件。

    public ConfigurableApplicationContext run(String... args) {
           ...
               ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
               ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
           }
    
    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
               DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
           // Create and configure the environment
           ConfigurableEnvironment environment = getOrCreateEnvironment();
           configureEnvironment(environment, applicationArguments.getSourceArgs());
           ConfigurationPropertySources.attach(environment);
    // 触发environmentPrepared事件
           listeners.environmentPrepared(bootstrapContext, environment);
           DefaultPropertiesPropertySource.moveToEnd(environment);
           configureAdditionalProfiles(environment);
           bindToSpringApplication(environment);
           if (!this.isCustomEnvironment) {
               environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
                       deduceEnvironmentClass());
           }
           ConfigurationPropertySources.attach(environment);
           return environment;
       }
    // 所有监听器触发environmentPrepared方法,SpringApplicationRunListener只有一个实现类EventPublishingRunListener,所以这里触发EventPublishingRunListener的environmentPrepared方法
    void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
           doWithListeners("spring.boot.application.environment-prepared",
                   (listener) -> listener.environmentPrepared(bootstrapContext, environment));
       }
    
    // EventPublishingRunListener发布事件ApplicationEnvironmentPreparedEvent
    @Override
       public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
               ConfigurableEnvironment environment) {
           this.initialMulticaster.multicastEvent(
                   new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
       }
    

    进入了第一个事件方法里

    @Override
        public void onApplicationEvent(ApplicationEvent event) {
            if (event instanceof ApplicationEnvironmentPreparedEvent) {
                onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
            }
            if (event instanceof ApplicationPreparedEvent) {
                onApplicationPreparedEvent((ApplicationPreparedEvent) event);
            }
            if (event instanceof ApplicationFailedEvent) {
                onApplicationFailedEvent((ApplicationFailedEvent) event);
            }
        }
    
    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
            ConfigurableEnvironment environment = event.getEnvironment();
            SpringApplication application = event.getSpringApplication();
            for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(event.getBootstrapContext())) {
                postProcessor.postProcessEnvironment(environment, application);
            }
        }
    

    在构造EnvironmentPostProcessorApplicationListener对象的时候,EnvironmentPostProcessorApplicationListener的成员变量postProcessorsFactory就赋值了EnvironmentPostProcessorsFactory ,并且这个EnvironmentPostProcessorsFactory 维护了所有的EnvironmentPostProcessor实现类,从META-INF/spring.factories里获取的。

    public EnvironmentPostProcessorApplicationListener() {
            this(EnvironmentPostProcessorsFactory
                    .fromSpringFactories(EnvironmentPostProcessorApplicationListener.class.getClassLoader()));
        }
    static EnvironmentPostProcessorsFactory fromSpringFactories(ClassLoader classLoader) {
            return new ReflectionEnvironmentPostProcessorsFactory(
                    SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, classLoader));
        }
    

    可以看到有这么多实现类,重点看ConfigDataEnvironmentPostProcessor,这是解析配置文件的。

    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
    

    回头看这里,循环调用所有的EnvironmentPostProcessor 的postProcessEnvironment方法,自然会调用ConfigDataEnvironmentPostProcessor的postProcessEnvironment方法

    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
            ConfigurableEnvironment environment = event.getEnvironment();
            SpringApplication application = event.getSpringApplication();
            for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(event.getBootstrapContext())) {
                postProcessor.postProcessEnvironment(environment, application);
            }
        }
    

    ConfigDataEnvironmentPostProcessor的postProcessEnvironment方法
    会构建一个ConfigDataEnvironment对象,这个对象比较重要

    void postProcessEnvironment(ConfigurableEnvironment environment, ResourceLoader resourceLoader,
                Collection<String> additionalProfiles) {
            try {
                this.logger.trace("Post-processing environment to add config data");
                resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader();
                getConfigDataEnvironment(environment, resourceLoader, additionalProfiles).processAndApply();
            }
            catch (UseLegacyConfigProcessingException ex) {
                this.logger.debug(LogMessage.format("Switching to legacy config file processing [%s]",
                        ex.getConfigurationProperty()));
                postProcessUsingLegacyApplicationListener(environment, resourceLoader);
            }
        }
    
    ConfigDataEnvironment getConfigDataEnvironment(ConfigurableEnvironment environment, ResourceLoader resourceLoader,
                Collection<String> additionalProfiles) {
            return new ConfigDataEnvironment(this.logFactory, this.bootstrapContext, environment, resourceLoader,
                    additionalProfiles);
        }
    

    ConfigDataEnvironment的静态块中可以看到,定义好了所有的配置文件存放的路径。一共有6个。也就是说会读取这6个路径下的yml文件或properties文件,并且有

    static final ConfigDataLocation[] DEFAULT_SEARCH_LOCATIONS;
        static {
            List<ConfigDataLocation> locations = new ArrayList<>();
            locations.add(ConfigDataLocation.of("optional:classpath:/"));
            locations.add(ConfigDataLocation.of("optional:classpath:/config/"));
            locations.add(ConfigDataLocation.of("optional:file:./"));
            locations.add(ConfigDataLocation.of("optional:file:./config/"));
            locations.add(ConfigDataLocation.of("optional:file:./config/*/"));
            DEFAULT_SEARCH_LOCATIONS = locations.toArray(new ConfigDataLocation[0]);
        };
    
    org.springframework.boot.context.config.ConfigDataLocationResolver=\
    org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
    org.springframework.boot.context.config.StandardConfigDataLocationResolver
    
    # ConfigData Loaders
    org.springframework.boot.context.config.ConfigDataLoader=\
    org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
    org.springframework.boot.context.config.StandardConfigDataLoader
    

    相关文章

      网友评论

          本文标题:springboot-解析yml文件

          本文链接:https://www.haomeiwen.com/subject/mqhogdtx.html