• Springboot源码之application.yaml读取过程


    application.yaml的读取发生在SpringApplication#prepareEnvironment()过程中

    public ConfigurableApplicationContext run(String... args) {
        try {
            ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            ......
        }
    }
    

    这个过程会触发一些监听器,去执行逻辑。其中在SimpleApplicationEventMulticaster广播器遍历监听器,遍历到EnvironmentPostProcessorApplicationListener,在这个类入口去处理资源文件。

    @Override
    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    	ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    	Executor executor = getTaskExecutor();
    	for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
    		if (executor != null) {
    			executor.execute(() -> invokeListener(listener, event));
    		}
    		else if (this.applicationStartup != null) {
    			StartupStep invocationStep = this.applicationStartup.start("spring.event.invoke-listener");
    			invokeListener(listener, event);
    			invocationStep.tag("event", event::toString);
    			if (eventType != null) {
    				invocationStep.tag("eventType", eventType::toString);
    			}
    			invocationStep.tag("listener", listener::toString);
    			invocationStep.end();
    		}
    		else {
    		    // 反射调用具体监听器onApplicationEvent方法
    			invokeListener(listener, event);
    		}
    	}
    }
    

    其后可根据下面提供的调用链去debug

    最后yaml、yml文件是用YamlPropertySourceLoader加载器去加载

    @Override
    public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
    	if (!ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
    		throw new IllegalStateException(
    				"Attempted to load " + name + " but snakeyaml was not found on the classpath");
    	}
    	List<Map<String, Object>> loaded = new OriginTrackedYamlLoader(resource).load();
    	if (loaded.isEmpty()) {
    		return Collections.emptyList();
    	}
    	List<PropertySource<?>> propertySources = new ArrayList<>(loaded.size());
    	for (int i = 0; i < loaded.size(); i++) {
    		String documentNumber = (loaded.size() != 1) ? " (document #" + i + ")" : "";
    		propertySources.add(new OriginTrackedMapPropertySource(name + documentNumber,
    				Collections.unmodifiableMap(loaded.get(i)), true));
    	}
    	return propertySources;
    }
    

    调用链:

    "main@1" prio=5 tid=0x1 nid=NA runnable
      java.lang.Thread.State: RUNNABLE
    	  at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:50)
    	  at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:45)
    	  at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:34)
    	  at org.springframework.boot.context.config.ConfigDataLoaders.load(ConfigDataLoaders.java:102)
    	  at org.springframework.boot.context.config.ConfigDataImporter.load(ConfigDataImporter.java:118)
    	  at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:82)
    	  at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:118)
    	  at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:230)
    	  at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:217)
    	  at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:88)
    	  at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:80)
    	  at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:100)
    	  at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:86)
    	  at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:203)
    	  at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:196)
    	  at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:170)
    	  at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:148)
    	  at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82)
    	  at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:63)
    	  at org.springframework.boot.SpringApplicationRunListeners$$Lambda$38.817686795.accept(Unknown Source:-1)
    	  at java.util.ArrayList.forEach(ArrayList.java:1257)
    	  at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
    	  at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111)
    	  at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:62)
    	  at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:362)
    	  at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    	  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309)
    	  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298)
    	  at com.java.study.StudyApplication.main(StudyApplication.java:13)
    
    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出。
  • 相关阅读:
    Python课程第三天作业
    Python课程第一天作业
    centos7安装Jenkins
    搭建zookeeper+kafka集群
    redis在实践中的一些常见问题以及优化思路
    部署redis4.0-cluster
    redis哨兵架构的基础知识及部署和管理
    Redis主从复制
    部署Redis4.x单机版及配置RDB和AOF持久化
    xshell使用密钥登陆linux
  • 原文地址:https://www.cnblogs.com/caozibiao/p/14039113.html
Copyright © 2020-2023  润新知