具有嵌套条件的 SpEL @Value

SpEL @Value with nested condition

我正在使用 @Value 注释,现在我希望它更复杂一些。我有两个配置值 - val1val2。我想按如下方式注入:如果配置中存在val1,则使用它。否则,如果 val2 为真,则注入 default1。如果为假,则注入 default2.

我试过类似的东西:

@Value("#{val1 ? val1 : (val2 ? 'default1' : 'default2')}")

但我不断收到:

`EL1008E`: property or filed 'val1' cannot be found on object of type 'org.springframeowrk.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?

当我尝试其他表达式时,例如 ${val1}'${val1}',它似乎仍然不起作用。

@Value 注释中嵌套条件的正确方法是什么,还是太复杂了?

我已经调整了表达式并写了一个小测试来说明变化。简而言之,使用${some.prop:defaultVal}定义一个默认值,使用${some.prop:}定义一个空String作为默认值。此外,在 SPEL 表达式中使用单引号 ' 来指示字符串值而不是引用。

尝试 TestPropertySource 来验证结果。我添加了第二个测试来表明当默认值不存在时,Spring 可能(并非总是)决定 return 占位符的文本表示。


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}");
    }
}

虽然上面的表达式有效,但我强烈建议使用 ConfigurationProperties, or a T expression type operator 来引用静态方法。当表达式变得更复杂时,当前的设置可能会变得更难读。