Property placeholder
This post deals with how spring manages to resolve a placeholder ${property-name}
to its actual value.
PropertyPlaceholder in location path
Our context file has a Foo bean and the file is located in a directory called springdemo
. Instead of hardcoding the location path, we will use a property placeholder and inject the actual location path externally.
<beans default-lazy-init="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="springdemo.Foo" id="foo"> </bean>
Since the sample context file is located in folder called springdemo
, in order to load the context we just need to pass the location as springdemo/testFoo.xml
to ClassPathXmlApplicationContext
constructor.
But instead of hard coding the directory, we would like to use a placeholder called ${springProj}
so that the directory can be fed externally. The test code below tries to load it but fails as we don’t have any property value set for the placeholder.
public void testPlaceholderWithoutPropInEnv() { try { new ClassPathXmlApplicationContext("${springProj}/testFoo.xml"); fail("should throw exception as we have not set springProj property to replace the placeholder"); } catch (IllegalArgumentException e) { } }
Environment
There must be a way to feed in a source of properties which we can use to replace the placeholders with their actual value. These properties can come from one or more sources, like we have java based properties and the system environment properties. The properties and the profile, together, makes the spring Environment.How do we inject these properties, when should we do it or in other words, when should we create an Environment
?
The Environment
will help us resolve property values as we run through the creation of context so it must be available as soon as we instantiate the ApplicationContext
.
In the below object diagram, we show that as we create ClassPathXmlApplicationContext
, the super class AbstractApplicationContext
automatically creates an environment.
![]() |
Create environment |
Spring Environment and Property Sources
By default, the environment relies on the java system properties and the system environment properties, called StandardEnvironment
.
createEnvironment()
.configurePropertySources()
, like StandardEnvironment
adds system properties and system environment to the property sources.
![]() |
Environment hierarchy |
Let’s try to pass the failing scenario we had before. In the below test code, we set the property springProj
.
public void testPropertyResolver() { System.setProperty("springProj", "springdemo"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("${springProj}/testFoo.xml"); Foo foo = (Foo) context.getBean("foo"); assertNotNull(foo); }
public void testPropertyResolver() { System.setProperty("app", "spring"); System.setProperty("springProj", "springdemo"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("${${app}Proj}/testFoo.xml"); Foo foo = (Foo) context.getBean("foo"); assertNotNull(foo); }
Property Source Examples
The below diagram shows the various property sources and the actual source that the object encapsulates.
![]() |
Property Sources |
Stub PropertySource
- It allows us to set the intended default position/order of the property sources beforehand.
- The stub property sources will be replaced by the actual ones when they are available.
![]() |
Servlet config and context stub property source |
In the below diagram, we show the order of property sources for a servlet environment. First the properties present in servletConfig will take precedence over those in servletContext, and
properties found in either of the above take precedence over those found in jndi.
Properties in any of the above will take precedence over system properties and environment variables.
Servlet Property sources
|
![]() |
Replace of stub property source with the actual ones |
Required Properties
springproj
as a required property. Spring validates them as the context is created, since the property is not available in the environment, context creation fails.public void testValidateRequiredProperty() { try { new ClassPathXmlApplicationContext("springdemo/testFoo.xml") { protected ConfigurableEnvironment createEnvironment() { ConfigurableEnvironment env = super.createEnvironment(); env.setRequiredProperties("springProj"); return env; } }; fail("should have failed as required property is missing"); } catch (MissingRequiredPropertiesException e) { } }