进入上一篇使用profile的load()方法(ConfigFileApplicationListener类中)
1、initializeProfiles();
1)进入initializeProfiles方法。初始化Profiles,将所有的profile增加到prifiles集合中
private void initializeProfiles() { // The default profile for these purposes is represented as null. We add it // first so that it is processed first and has lowest priority. this.profiles.add(null); Set<Profile> activatedViaProperty = getProfilesActivatedViaProperty(); this.profiles.addAll(getOtherActiveProfiles(activatedViaProperty)); // Any pre-existing active profiles set via property sources (e.g. // System properties) take precedence over those added in config files. addActiveProfiles(activatedViaProperty); if (this.profiles.size() == 1) { // only has null profile for (String defaultProfileName : this.environment.getDefaultProfiles()) { Profile defaultProfile = new Profile(defaultProfileName, true); this.profiles.add(defaultProfile); } } }
2、load(profile, this::getPositiveProfileFilter, addToLoaded(MutablePropertySources::addLast, false));
遍历prifles,
第一个prifile为空,进入load方法
private void load(Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) { getSearchLocations().forEach((location) -> { boolean isFolder = location.endsWith("/"); Set<String> names = isFolder ? getSearchNames() : NO_SEARCH_NAMES; names.forEach((name) -> load(location, name, profile, filterFactory, consumer)); }); }
进入getSearchLocations方法,获得如下图,classpath:/等查询路径
然后遍历上一步获取的查询路径
进入names.forEach((name) -> load(location, name, profile, filterFactory, consumer))的load方法,name值为application
然后进入loadForFileExtension(loader, location + name, "." + fileExtension, profile, filterFactory, consumer);
最终进入load(loader, prefix + fileExtension, profile, profileFilter, consumer);这个方法
private void load(PropertySourceLoader loader, String location, Profile profile, DocumentFilter filter, DocumentConsumer consumer) { try { Resource resource = this.resourceLoader.getResource(location); if (resource == null || !resource.exists()) { if (this.logger.isTraceEnabled()) { StringBuilder description = getDescription("Skipped missing config ", location, resource, profile); this.logger.trace(description); } return; } if (!StringUtils.hasText(StringUtils.getFilenameExtension(resource.getFilename()))) { if (this.logger.isTraceEnabled()) { StringBuilder description = getDescription("Skipped empty config extension ", location, resource, profile); this.logger.trace(description); } return; } String name = "applicationConfig: [" + location + "]"; List<Document> documents = loadDocuments(loader, name, resource); if (CollectionUtils.isEmpty(documents)) { if (this.logger.isTraceEnabled()) { StringBuilder description = getDescription("Skipped unloaded config ", location, resource, profile); this.logger.trace(description); } return; } List<Document> loaded = new ArrayList<>(); for (Document document : documents) { if (filter.match(document)) { addActiveProfiles(document.getActiveProfiles()); addIncludedProfiles(document.getIncludeProfiles()); loaded.add(document); } } Collections.reverse(loaded); if (!loaded.isEmpty()) { loaded.forEach((document) -> consumer.accept(profile, document)); if (this.logger.isDebugEnabled()) { StringBuilder description = getDescription("Loaded config file ", location, resource, profile); this.logger.debug(description); } } } catch (Exception ex) { throw new IllegalStateException("Failed to load property " + "source from location '" + location + "'", ex); } }
然后进入List<Document> documents = loadDocuments(loader, name, resource);
private List<Document> loadDocuments(PropertySourceLoader loader, String name, Resource resource) throws IOException { DocumentsCacheKey cacheKey = new DocumentsCacheKey(loader, resource); List<Document> documents = this.loadDocumentsCache.get(cacheKey); if (documents == null) { List<PropertySource<?>> loaded = loader.load(name, resource); documents = asDocuments(loaded); this.loadDocumentsCache.put(cacheKey, documents); } return documents; }
进入List<PropertySource<?>> loaded = loader.load(name, resource); 加载后的属性如下图所示
3、resetEnvironmentProfiles(this.processedProfiles);
设置激活的prifile有哪些
private void resetEnvironmentProfiles(List<Profile> processedProfiles) { String[] names = processedProfiles.stream() .filter((profile) -> profile != null && !profile.isDefaultProfile()).map(Profile::getName) .toArray(String[]::new); this.environment.setActiveProfiles(names); }
4、load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));
防止前面循环没有进入,load默认的profile
5、addLoadedPropertySources(); 将获得的profile的属性增加到属性源中
private void addLoadedPropertySources() { MutablePropertySources destination = this.environment.getPropertySources(); List<MutablePropertySources> loaded = new ArrayList<>(this.loaded.values()); Collections.reverse(loaded); String lastAdded = null; Set<String> added = new HashSet<>(); for (MutablePropertySources sources : loaded) { for (PropertySource<?> source : sources) { if (added.add(source.getName())) { addLoadedPropertySource(destination, lastAdded, source); lastAdded = source.getName(); } } } }
如下图所示