Spring 3 introduced a new expression language (SpEL) that can be used in bean definitions. The syntax itself is reasonably well defined.
It is not clear how, if at all, SpEL interacts with the property placeholder syntax that was already present in previous versions. Does SpEL have support for property placeholders, or do I need to combine the syntax of both mechanisms and hope that they combine?
Let me give you a concrete example. I want to use the syntax of the ${xyz} property, but with the addition of the "default" syntax provided by the elis operator to handle cases when ${xyz} is undefined.
I tried the following syntaxes without success:
#{xyz?:'defaultValue'}#{${xyz}?:'defaultValue'}
First one gives me
The field or property 'x' cannot be found on an object of type 'Org.springframework.beans.factory.config.BeanExpressionContext'
which suggests that SpEL does not recognize this as a placeholder for properties.
The second syntax throws an exception saying that the placeholder is not recognized, so the calling placeholder is called, but does not work properly, because the property is undefined.
The documents do not mention this interaction, so either such a thing is impossible or not documented.
Who succeeded?
Ok, I came up with a small, standalone test case. It all works as it is:
Bean definitions first:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd "> <context:property-placeholder properties-ref="myProps"/> <util:properties id="myProps"> <prop key="xyz">Value A</prop> </util:properties> <bean id="testBean" class="test.Bean"> <property name="value" value="${xyz}"/> </bean> </beans>
Then the trivial class bean:
batch test;
public class Bean { String value; public void setValue(String value) { this.value = value; } }
And finally, a test case:
package test; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class PlaceholderTest { private @Resource Bean testBean; @Test public void valueCheck() { assertThat(testBean.value, is("Value A")); } }
The task is to come up with a SpEL expression in the beans file, which allows me to specify a default value in cases where ${xyz} cannot be resolved, and this default value should be specified as part of the expression, and not externalized in another set of properties.