I'm using the @Value
annotation, and I want it to be a bit more complex now. I have two config values - val1
, and val2
. I want to inject it as follows: If val1
exists in the configuration, use it. Else, if val2
is true, inject default1
. If it's false, inject default2
.
I tried something like:
@Value("#{val1 ? val1 : (val2 ? 'default1' : 'default2')}")
But I keep getting:
`EL1008E`: property or filed 'val1' cannot be found on object of type 'org.springframeowrk.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
When I try other expressions, such as ${val1}
or '${val1}'
it still does not seem to work.
What's the correct way to do nested conditions in the @Value
annotation, or is it too complex?
I have adjusted the expression and written a small test to illustrate the change. In short, use ${some.prop:defaultVal}
to define a default value and use ${some.prop:}
to define an empty String as a default value. Also, use single quotes '
in a SPEL expression to indicate the String value instead of a reference.
Play around with the TestPropertySource
to verify the outcome. I have added a second test to show that when a default value is not present, Spring might (not always) decide to return the textual representation of the placeholder.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@TestPropertySource(properties = {"val1=v1", "val2=v2"})
public class SomeTest {
@Value("#{ '${val1:}' != '' ? '${val1}' : ('${val2:}' != '' ? 'default1' : 'default2')}")
private String testVal;
@Value("${nonExistingValue}")
private String nonExistingValue;
@Test
public void test() {
assertThat(testVal).isEqualTo("v1");
}
@Test
public void testNonExistingValue() {
assertThat(nonExistingValue).isEqualTo("${nonExistingValue}");
}
}
Although the above expression works, I would highly recommend to use ConfigurationProperties
, or a T expression type operator
referring to a static method. The current set up might become even less readable when the expressions becomes more complex.