继续
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结尾的用另一个
我用的是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; } } }继续深入
可以看到,总算把我配合文件的内容给读到了,然后放入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的整个流程,代码虽然贴的比较多,但可以让初学者也可以跟着这个步骤完整的理解一遍,代码中的关键步骤我都用中文标明了,其它没标注部分不是这章的重点,想研究的自行研究