ApplicationContext ctx = new GenericApplicationContext();
Environment env = ctx.getEnvironment();
boolean containsFoo = env.containsProperty("foo");
System.out.println("Does my environment contain the 'foo' property? " + containsFoo);
PropertySource abstraction
Spring’s Environment
abstraction provides search operations over a configurable
hierarchy of property sources. To explain fully, consider the following:
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 {api-spring-framework}/core/env/PropertySource.html[PropertySource
]
objects. A PropertySource
is a simple abstraction over any source of key-value pairs, and
Spring’s {api-spring-framework}/core/env/StandardEnvironment.html[StandardEnvironment
]
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()
).
Note
|
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.
Tip
|
The search performed is hierarchical. By default, system properties have precedence over
environment variables, so if the For a common
|
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
any foo
property in any other PropertySource
. The
{api-spring-framework}/core/env/MutablePropertySources.html[MutablePropertySources
]
API exposes a number of methods that allow for precise manipulation of the set of
property sources.
@PropertySource
The {api-spring-framework}/context/annotation/PropertySource.html[@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.
Placeholder resolution in statements
Historically, the value of placeholders in elements could be resolved only against JVM system properties or environment variables. No longer is this the case. Because the Environment abstraction is integrated throughout the container, it’s easy to route resolution of placeholders through it. This means that you may configure the resolution process in any way you like: change the precedence of searching through system properties and environment variables, or remove them entirely; add your own property sources to the mix as appropriate.
Concretely, the following statement works regardless of where the customer
property is defined, as long as it is available in the Environment
:
<beans>
<import resource="com/bank/service/${customer}-config.xml"/>
</beans>