栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot加载配置文件源码解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot加载配置文件源码解析

        SpringBoot通过事件广播机制通知ConfigFileApplicationListener这个监听器来加载properties和yaml文件。关于SpringBoot事件编程模型可参考:SpringBoot事件编程模型解析。

        SpringBoot一站式启动过程中,会经过环境准备阶段:

ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);

        该过程中,会向监听者广播环境准备完毕的事件:

listeners.environmentPrepared(environment);

        其中ConfigFileApplicationListener监听者接收到该事件后, 会委托EnvionmentPostProcesor环境后置处理器来加载配置文件,这里的ConfigFileApplicationListener的另外一个角色正好是环境后置处理器,所以最终文件加载还是在ConfigFileApplicationListener中完成的。

//继承了环境后置处理器和应用程序监听器
public class ConfigFileApplicationListener
		implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
    ...
}

        ConfigFileApplicationListener中加载配置文件总领代码如下:       

	protected void addPropertySources(ConfigurableEnvironment environment,
			ResourceLoader resourceLoader) {
		RandomValuePropertySource.addToEnvironment(environment);
		new Loader(environment, resourceLoader).load();
	}

         加载规则如下:先看命令行中是否指定spring.config.location,如果有,则加载指定地址配置文件,如果没有,则按classpath:/,classpath:/config/,file:./,file:./config/优先级加载该路径下的配置文件,可配置spring.profiles.active或者spring.profiles.include加载application-xxx.properties文件,也可配置spring.config.additional-location加载其他路径下的配置文件。

        property和yaml具体的资源加载器分别是:PropertiesPropertySourceLoader、YamlPropertySourceLoader,将配置文件读取到内存其实就是JAVA IO的过程,以classpath路径下配置文件加载为例:

public class PropertiesPropertySourceLoader implements PropertySourceLoader {

	private static final String XML_FILE_EXTENSION = ".xml";

	@Override
	public String[] getFileExtensions() {
		return new String[] { "properties", "xml" };
	}

	@Override
	public List> load(String name, Resource resource)
			throws IOException {
		Map properties = loadProperties(resource);
		if (properties.isEmpty()) {
			return Collections.emptyList();
		}
		return Collections
				.singletonList(new OriginTrackedMapPropertySource(name, properties));
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private Map loadProperties(Resource resource) throws IOException {
		String filename = resource.getFilename();
		if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
			return (Map) PropertiesLoaderUtils.loadProperties(resource);
		}
        //加载
		return new OriginTrackedPropertiesLoader(resource).load();
	}

}

        load过程如下:        

	public Map load(boolean expandLists) throws IOException {
        //通过ClasspathResource中获取字符流
		try (CharacterReader reader = new CharacterReader(this.resource)) {
			Map result = new linkedHashMap<>();
			StringBuilder buffer = new StringBuilder();
			while (reader.read()) {
				String key = loadKey(buffer, reader).trim();
				if (expandLists && key.endsWith("[]")) {
					key = key.substring(0, key.length() - 2);
					int index = 0;
					do {
						OriginTrackedValue value = loadValue(buffer, reader, true);
						put(result, key + "[" + (index++) + "]", value);
						if (!reader.isEndOfLine()) {
							reader.read();
						}
					}
					while (!reader.isEndOfLine());
				}
				else {
					OriginTrackedValue value = loadValue(buffer, reader, false);
					put(result, key, value);
				}
			}
			return result;
		}
	}

        从文件到输入流:

	@Override
	public InputStream getInputStream() throws IOException {
		InputStream is;
		if (this.clazz != null) {
			is = this.clazz.getResourceAsStream(this.path);
		}
		else if (this.classLoader != null) {
			is = this.classLoader.getResourceAsStream(this.path);
		}
		else {
			is = ClassLoader.getSystemResourceAsStream(this.path);
		}
		if (is == null) {
			throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
		}
		return is;
	}

     

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322576.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号