Look at the most simple spring boot environment in some of what first spring boot version is 1.5.9
@RequestMapping(value = "/hello")
@RestController
public class HelloWorld {
@Autowired
private AbstractEnvironment environment;
@RequestMapping(value = "/world", method = RequestMethod.GET)
public String world() {
System.out.println(environment);
System.out.println(environment.getSystemEnvironment());
System.out.println(environment.getSystemProperties());
for (String s : environment.getActiveProfiles()){
System.out.println(s);
}
System.out.println("qwe");
for (String s : environment.getDefaultProfiles()){
System.out.println(s);
}
return "qwe";
}
}
Test code
StandardServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[MapPropertySource {name='server.ports'}, StubPropertySource {name='servletConfigInitParams'}, ServletContextPropertySource {name='servletContextInitParams'}, MapPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, PropertiesPropertySource {name='applicationConfig: [classpath:/application.properties]'}]}
This is the environment inside all variables, then take a look at where these environmental variables are generated. First, the method can be entered from the run can be seen prepareEnvironment method used to generate the environment.
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
ConfigurableEnvironment environment = this.getOrCreateEnvironment();
this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared((ConfigurableEnvironment)environment);
if (!this.webEnvironment) {
environment = (new EnvironmentConverter(this.getClassLoader())).convertToStandardEnvironmentIfNecessary((ConfigurableEnvironment)environment);
}
return (ConfigurableEnvironment)environment;
}
Just look at three methods can getOrCreateEnvironment, configureEnvironment, environmentPrepared, take a look at getOrCreateEnvironment
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
} else {
return (ConfigurableEnvironment)(this.webEnvironment ? new StandardServletEnvironment() : new StandardEnvironment());
}
}
Here only a step, new StandardServletEnvironment (). Then take a look at some of what will be initialized
StandardServletEnvironment-> StandardEnvironment-> AbstractEnvironment. This is an inheritance, go initialization in the constructor AbstractEnvironment
public AbstractEnvironment() {
this.propertySources = new MutablePropertySources(this.logger);
this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
this.customizePropertySources(this.propertySources);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Initialized " + this.getClass().getSimpleName() + " with PropertySources " + this.propertySources);
}
}
customizePropertySources method to initialize, then found a way in StandardServletEnvironment
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource("servletConfigInitParams"));
propertySources.addLast(new StubPropertySource("servletContextInitParams"));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource("jndiProperties"));
}
super.customizePropertySources(propertySources);
}
Here some initialization parameters of the servlet. There is also a method to call the parent class, let's look at the method in the parent class
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new MapPropertySource("systemProperties", this.getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment()));
}
Found here initialize the system environment variables.
So far most of the initialization has been completed.
Then take a look configureEnvironment
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
this.configurePropertySources(environment, args);
this.configureProfiles(environment, args);
}
Into the first method
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
}
if (this.addCommandLineProperties && args.length > 0) {
String name = "commandLineArgs";
if (sources.contains(name)) {
PropertySource<?> source = sources.get(name);
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(new SimpleCommandLinePropertySource(name + "-" + args.hashCode(), args));
composite.addPropertySource(source);
sources.replace(name, composite);
} else {
sources.addFirst(new SimpleCommandLinePropertySource(args));
}
}
}
Here is the command-line parameters to initialize
Finally, look at the environmentPrepared, essentially ConfigFileApplicationListener class
When broadcasting, and calls onApplicationEnvironmentPreparedEvent
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
List<EnvironmentPostProcessor> postProcessors = this.loadPostProcessors();
postProcessors.add(this);
AnnotationAwareOrderComparator.sort(postProcessors);
Iterator var3 = postProcessors.iterator();
while(var3.hasNext()) {
EnvironmentPostProcessor postProcessor = (EnvironmentPostProcessor)var3.next();
postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
}
}
Method entered postProcessEnvironment
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
this.addPropertySources(environment, application.getResourceLoader());
this.configureIgnoreBeanInfo(environment);
this.bindToSpringApplication(environment, application);
}
Method entered addPropertySources
protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
RandomValuePropertySource.addToEnvironment(environment);
(new ConfigFileApplicationListener.Loader(environment, resourceLoader)).load();
}
Here RandomValuePropertySource added environment variables
Then he sent the last load .yml and the .properties file.
Into the load () method
public void load() {
this.propertiesLoader = new PropertySourcesLoader();
this.activatedProfiles = false;
this.profiles = Collections.asLifoQueue(new LinkedList());
this.processedProfiles = new LinkedList();
Set<ConfigFileApplicationListener.Profile> initialActiveProfiles = this.initializeActiveProfiles();
this.profiles.addAll(this.getUnprocessedActiveProfiles(initialActiveProfiles));
if (this.profiles.isEmpty()) {
String[] var2 = this.environment.getDefaultProfiles();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
String defaultProfileName = var2[var4];
ConfigFileApplicationListener.Profile defaultProfile = new ConfigFileApplicationListener.Profile(defaultProfileName, true);
if (!this.profiles.contains(defaultProfile)) {
this.profiles.add(defaultProfile);
}
}
}
this.profiles.add((Object)null);
ConfigFileApplicationListener.Profile profile;
label41:
for(; !this.profiles.isEmpty(); this.processedProfiles.add(profile)) {
profile = (ConfigFileApplicationListener.Profile)this.profiles.poll();
Iterator var8 = this.getSearchLocations().iterator();
while(true) {
while(true) {
if (!var8.hasNext()) {
continue label41;
}
String location = (String)var8.next();
if (!location.endsWith("/")) {
this.load(location, (String)null, profile);
} else {
Iterator var10 = this.getSearchNames().iterator();
while(var10.hasNext()) {
String name = (String)var10.next();
this.load(location, name, profile);
}
}
}
}
}
this.addConfigurationProperties(this.propertiesLoader.getPropertySources());
}
Look at the lowermost position is the location where the cycle required file, the order is such that row down. file: ./ config /, file: ./, classpath: / config /, classpath: /. name is the application, profile may be a "default", which correspond to the two application-default.yml.
Look at the inside of the load method
private void load(String location, String name, ConfigFileApplicationListener.Profile profile) {
String group = "profile=" + (profile == null ? "" : profile);
String ext;
if (!StringUtils.hasText(name)) {
this.loadIntoGroup(group, location, profile);
} else {
for(Iterator var5 = this.propertiesLoader.getAllFileExtensions().iterator(); var5.hasNext(); this.loadIntoGroup(group, location + name + "." + ext, profile)) {
ext = (String)var5.next();
if (profile != null) {
this.loadIntoGroup(group, location + name + "-" + profile + "." + ext, (ConfigFileApplicationListener.Profile)null);
Iterator var7 = this.processedProfiles.iterator();
while(var7.hasNext()) {
ConfigFileApplicationListener.Profile processedProfile = (ConfigFileApplicationListener.Profile)var7.next();
if (processedProfile != null) {
this.loadIntoGroup(group, location + name + "-" + processedProfile + "." + ext, profile);
}
}
this.loadIntoGroup(group, location + name + "-" + profile + "." + ext, profile);
}
}
}
}
There can be seen a this.loadIntoGroup (group, location + name + "." + Ext, profile) inside the for loop
application.properties is here initialized