Reputation: 2076
I am confused about how Spring Environment works. I thought it is basically a singleton bean in the ApplicationContext
and anytime I load PropertySources
into my AppCtx, they combine into this single Environment
automatically. However, I am seeing this logged many times in my app, which means the constructor of AbstractEnvironment
is getting called many times:
2015-01-06 12:16:26,858 DEBUG (main) [org.springframework.core.env.StandardEnvironment] Adding [systemProperties] PropertySource with lowest search precedence
2015-01-06 12:16:26,858 DEBUG (main) [org.springframework.core.env.StandardEnvironment] Adding [systemEnvironment] PropertySource with lowest search precedence
2015-01-06 12:16:26,858 DEBUG (main) [org.springframework.core.env.StandardEnvironment] Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
The results are that I do things like:
@Autowire
Environment environment;
String propertyIExpect = environment.getProperty("myprop");
And I get an instance of the Environment
, but no properties I expected to be present are in it.
I expected them to have been added to this auto-wired Environment
when I added this XML to my Spring Boot application context:
<context:property-placeholder location="classpath:/spring/environment/${ctms.env}/application.properties" order="1"/>
<context:property-placeholder location="classpath:build.info" order="2"/>
Then again, sometimes the Environment
properties are there as shown in this logging:
2015-01-06 12:16:37,433 TRACE (main) [org.springframework.core.env.PropertySourcesPropertyResolver] getProperty("ctms.env", String)
2015-01-06 12:16:37,433 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'ctms.env' in [servletConfigInitParams]
2015-01-06 12:16:37,433 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'ctms.env' in [servletContextInitParams]
2015-01-06 12:16:37,433 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'ctms.env' in [systemProperties]
2015-01-06 12:16:37,433 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Found key 'ctms.env' in [systemProperties] with type [String] and value 'dev'
2015-01-06 12:16:37,438 DEBUG (main) [org.springframework.core.env.MutablePropertySources] Adding [environmentProperties] PropertySource with lowest search precedence
2015-01-06 12:16:37,438 INFO (main) [org.springframework.context.support.PropertySourcesPlaceholderConfigurer] Loading properties file from class path resource [spring/environment/dev/application.properties]
2015-01-06 12:16:37,438 DEBUG (main) [org.springframework.core.env.MutablePropertySources] Adding [localProperties] PropertySource with lowest search precedence
2015-01-06 12:16:37,443 TRACE (main) [org.springframework.core.env.PropertySourcesPropertyResolver] getProperty("database.connection.url", String)
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [environmentProperties]
2015-01-06 12:16:37,443 TRACE (main) [org.springframework.core.env.PropertySourcesPropertyResolver] getProperty("database.connection.url", String)
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [servletConfigInitParams]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [servletContextInitParams]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [systemProperties]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [systemEnvironment]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [random]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [applicationConfig: [classpath:/application.properties]]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Could not find key 'database.connection.url' in any property source. Returning [null]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Searching for key 'database.connection.url' in [localProperties]
2015-01-06 12:16:37,443 DEBUG (main) [org.springframework.core.env.PropertySourcesPropertyResolver] Found key 'database.connection.url' in [localProperties] with type [String] and value 'jdbc:oracle:thin:@somehost:someport/foo'
NOTE: I am also seeing this in the Spring Boot logs 2 times:
12:19:03,387 INFO [TomcatEmbeddedServletContainer] Tomcat started on port(s): 8080/http
I would've expected this one time at the end. Perhaps this is related? Am I somehow creating multiple ApplicationContext
s in my Spring Boot app?
Upvotes: 1
Views: 4719
Reputation: 2076
From the advice posted here, I no longer load the properties file: classpath:/spring/${ctms.env}/application.properties from a <context:property-placeholder>
XML.
This is how I resolved my Environment properties issue:
Since ${ctms.env} is essentially the environment we are running in and also reflected in a Spring active profile (e.g., dev, test, stage, prod), I ended up using Spring Boot's feature to auto-load active profile properties files "by convention" for me.
To clarify, this Spring Boot feature will look for .properties files in specific locations based on the active profiles. Like this:
For a Spring Active Profile = "foo", it would auto-load this file, if it exists:
WEB-INF/classes/config/application-foo.properties
For my solution, I re-locate and re-name the properties file in my Spring Boot WAR to like this:
/WEB-INF/classes/config/application-${ctms-env}.properties
It basically ends up being something like: For "dev" Spring Active Profile:
/WEB-INF/classes/config/application-dev.properties
For "test" Spring Active Profile:
/WEB-INF/classes/config/application-test.properties
For "stage" Spring Active Profile:
/WEB-INF/classes/config/application-stage.properties
etc.
I didn't have to re-write any properties files. I just had to re-package them the way Spring Boot "conventions" want to find/load them. And, then of course, stop loading via the XML way. And it works great.
Upvotes: 0
Reputation: 58094
An XML <context:property-placeholder/>
is not added to the Environment
. The DEBUG logs are just noise, so probably ignorable. If you need it in the Environment
then use the Spring Boot APIs to set the property locations (or possibly us @PropertySource
).
Upvotes: 1