SpringBoot读取配置文件源码探究 (3)

继续

private PropertySource<?> loadIntoGroup(String identifier, String location, Profile profile) { try { //入口 return doLoadIntoGroup(identifier, location, profile); } catch (Exception ex) { throw new IllegalStateException( "Failed to load property source from location '" + location + "'", ex); } }

do开头都是正式要干事了

private PropertySource<?> doLoadIntoGroup(String identifier, String location, Profile profile) throws IOException { Resource resource = this.resourceLoader.getResource(location); PropertySource<?> propertySource = null; StringBuilder msg = new StringBuilder(); if (resource != null && resource.exists()) { String name = "applicationConfig: [" + location + "]"; String group = "applicationConfig: [" + identifier + "]"; // 加载入口 propertySource = this.propertiesLoader.load(resource, group, name, (profile != null) ? profile.getName() : null); if (propertySource != null) { msg.append("Loaded "); handleProfileProperties(propertySource); } else { msg.append("Skipped (empty) "); } } else { msg.append("Skipped "); } msg.append("config file "); msg.append(getResourceDescription(location, resource)); if (profile != null) { msg.append(" for profile ").append(profile); } if (resource == null || !resource.exists()) { msg.append(" resource not found"); this.logger.trace(msg); } else { this.logger.debug(msg); } return propertySource; }

load内容,这里有两个加载器,看名字也知道了,yml结尾的文件肯定用YamlPropertySourceLoader才能加载,properties结尾的用另一个

public PropertySource<?> load(Resource resource, String group, String name, String profile) throws IOException { if (isFile(resource)) { String sourceName = generatePropertySourceName(name, profile); for (PropertySourceLoader loader : this.loaders) { if (canLoadFileExtension(loader, resource)) { // 干事的入口 PropertySource<?> specific = loader.load(sourceName, resource, profile); addPropertySource(group, specific); return specific; } } } return null; }

我用的是yml,所以在YamlPropertySourceLoader类

@Override public PropertySource<?> load(String name, Resource resource, String profile) throws IOException { if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) { Processor processor = new Processor(resource, profile); //真正的处理类 Map<String, Object> source = processor.process(); if (!source.isEmpty()) { return new MapPropertySource(name, source); } } return null; } public Map<String, Object> process() { final Map<String, Object> result = new LinkedHashMap<String, Object>(); //接近了 process(new MatchCallback() { @Override public void process(Properties properties, Map<String, Object> map) { result.putAll(getFlattenedMap(map)); } }); return result; } 1.2.7. process protected void process(MatchCallback callback) { Yaml yaml = createYaml(); for (Resource resource : this.resources) { //更近了 boolean found = process(callback, yaml, resource); if (this.resolutionMethod == ResolutionMethod.FIRST_FOUND && found) { return; } } }

继续深入

image.png


可以看到,总算把我配合文件的内容给读到了,然后放入callback

private boolean process(MatchCallback callback, Yaml yaml, Resource resource) { int count = 0; try { if (logger.isDebugEnabled()) { logger.debug("Loading from YAML: " + resource); } //读取文件 Reader reader = new UnicodeReader(resource.getInputStream()); try { for (Object object : yaml.loadAll(reader)) { //总算拿到了 if (object != null && process(asMap(object), callback)) { count++; if (this.resolutionMethod == ResolutionMethod.FIRST_FOUND) { break; } } } if (logger.isDebugEnabled()) { logger.debug("Loaded " + count + " document" + (count > 1 ? "s" : "") + " from YAML resource: " + resource); } } finally { reader.close(); } } catch (IOException ex) { handleProcessError(resource, ex); } return (count > 0); }

结果就存入了result

这样之后返回去看,你就会看到它存入了MapPropertySource属性资源,在之后就会被用上了

1.3. 总结

我通过一步步的代码跟踪,解析了SpringBoot读取application.yml的整个流程,代码虽然贴的比较多,但可以让初学者也可以跟着这个步骤完整的理解一遍,代码中的关键步骤我都用中文标明了,其它没标注部分不是这章的重点,想研究的自行研究

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxydy.html