Spring boot 項目啟動過程中:
org.springframework.boot.SpringApplication#prepareEnvironment
當程序步入listeners.environmentPrepared(environment);這里后,就會讀取配置文件中信息。
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); configureEnvironment(environment, applicationArguments.getSourceArgs()); listeners.environmentPrepared(environment); bindToSpringApplication(environment); if (!this.isCustomEnvironment) { environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); } ConfigurationPropertySources.attach(environment); return environment; }
這句代碼不好調試listeners.environmentPrepared(environment);
但可以換一種方式,找到上圖中的這個類:org.springframework.boot.env.OriginTrackedMapPropertySource
在斷點處打上斷點,就可以看到系統是如何運行的:下面是堆棧信息
在堆棧信息中,可以看到這個類:org.springframework.boot.context.config.ConfigFileApplicationListener
這個類里面的包含一些配置信息:
private static final String DEFAULT_PROPERTIES = "defaultProperties"; // Note the order is from least to most specific (last one wins) private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/"; private static final String DEFAULT_NAMES = "application"; private static final Set<String> NO_SEARCH_NAMES = Collections.singleton(null); private static final Bindable<String[]> STRING_ARRAY = Bindable.of(String[].class); /** * The "active profiles" property name. */ public static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active"; /** * The "includes profiles" property name. */ public static final String INCLUDE_PROFILES_PROPERTY = "spring.profiles.include"; /** * The "config name" property name. */ public static final String CONFIG_NAME_PROPERTY = "spring.config.name"; /** * The "config location" property name. */ public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";
一個properties. 一個yaml配置sourceloader
加載yaml文件的類是YamlPropertySourceLoader
public class YamlPropertySourceLoader implements PropertySourceLoader { @Override public String[] getFileExtensions() { return new String[] { "yml", "yaml" }; } @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, loaded.get(i))); } return propertySources; } }
注如果是雲環境,則首先加載的是bootstrap.yml, environment也是StandardEnvironment,非servlet環境。這是和Spring boot有很大的不同,加載完成后,再嵌套一StandardServletEnvironment.
加載完成后,再嵌套一StandardServletEnvironment.