PropertySource Abstraction
Spring’s Environment abstraction provides search operations over a configurable hierarchy of property sources. To explain fully, consider the following:
ApplicationContext ctx = new GenericApplicationContext(); Environment env = ctx.getEnvironment(); boolean containsFoo = env.containsProperty("foo"); System.out.println("Does my environment contain the 'foo' property? " + containsFoo);
In the snippet above, we see a high-level way of asking Spring whether the foo
property is defined for the current environment. To answer this question, the Environment
object performs a search over a set of PropertySource
objects. A PropertySource
is a simple abstraction over any source of key-value pairs, and Spring’sStandardEnvironment
is configured with two PropertySource objects — one representing the set of JVM system properties (a la System.getProperties()
) and one representing the set of system environment variables (a la System.getenv()
).
These default property sources are present for |
Concretely, when using the StandardEnvironment
, the call to env.containsProperty("foo")
will return true if a foo
system property or foo
environment variable is present at runtime.
The search performed is hierarchical. By default, system properties have precedence over environment variables, so if the |
Most importantly, the entire mechanism is configurable. Perhaps you have a custom source of properties that you’d like to integrate into this search. No problem — simply implement and instantiate your own PropertySource
and add it to the set of PropertySources
for the current Environment
:
ConfigurableApplicationContext ctx = new GenericApplicationContext(); MutablePropertySources sources = ctx.getEnvironment().getPropertySources(); sources.addFirst(new MyPropertySource());
In the code above, MyPropertySource
has been added with highest precedence in the search. If it contains a foo
property, it will be detected and returned ahead of anyfoo
property in any other PropertySource
. The MutablePropertySources
API exposes a number of methods that allow for precise manipulation of the set of property sources.
5.13.4 @PropertySource
The @PropertySource
annotation provides a convenient and declarative mechanism for adding a PropertySource
to Spring’s Environment
.
Given a file "app.properties" containing the key/value pair testbean.name=myTestBean
, the following @Configuration
class uses @PropertySource
in such a way that a call to testBean.getName()
will return "myTestBean".
@Configuration @PropertySource("classpath:/com/myco/app.properties") public class AppConfig { @Autowired Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("testbean.name")); return testBean; } }
Any ${...}
placeholders present in a @PropertySource
resource location will be resolved against the set of property sources already registered against the environment. For example:
@Configuration @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties") public class AppConfig { @Autowired Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("testbean.name")); return testBean; } }
Assuming that "my.placeholder" is present in one of the property sources already registered, e.g. system properties or environment variables, the placeholder will be resolved to the corresponding value. If not, then "default/path" will be used as a default. If no default is specified and a property cannot be resolved, an IllegalArgumentException
will be thrown.