【发布时间】:2018-09-14 03:32:17
【问题描述】:
我已经熟悉 Spring 的 @Value 注释的基本行为,可以将字段设置为项目属性的值,如下所示:
项目的属性文件
foo.bar=value
项目的配置类
@Configuration
public class MyConfig {
@Value("${foo.bar}")
private String myValue;
}
但是,我正在尝试使用条件配置制作 SpringBoot 入门项目,并希望将属性名称标准化为有用的名称,例如“com.mycompany.propertygroup.propertyname”,但为了简化过渡并鼓励采用,我想要暂时也支持旧的属性名称,因此想知道是否有某种方法可以允许多个属性名称设置相同的字段?例如:
我的理论入门配置
@Configuration
public class MyConfig {
@Value("${com.mycompany.propertygroup.propertyname}" || "${oldconvention.property}")
private String myValue;
}
项目 A 的属性
oldconvention.property=value
项目 B 的财产
com.mycompany.propertygroup.propertyname=value
我似乎找不到任何文档或 SO 答案,说明这是否可能以及如何实现它......所以我想知道它是否可能,或者如果不是,是否有替代@Value注解可以达到同样的效果吗?
编辑澄清: 我不想跟踪多个值,所以我不需要关于如何获取多个值的说明……目标是合并成一个可能有多个名称的 SINGLE VALUE。在实践中,每个使用启动器的项目只有一个名称-值......只有在极少数情况下,当有人可能忘记删除旧属性时,才会使用每个属性名称(无论如何它可能具有相同的值)。在这种情况下,新的公约名称值将是唯一使用的。
更新
虽然提供的 SpEL 表达式答案在两个属性都存在时有效,但当只有一个属性名称存在时,应用程序上下文无法加载。示例:
更新的配置类
@Value("#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}"
private String myProperty;
更新的属性文件
com.mycompany.propertygroup.propertyname=somevalue
错误
Caused by: java.lang.IllegalArgumentException:
Could not resolve placeholder 'oldconvention.propertyname' in value
"#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}"
要求两个属性名称都存在违背了目的,即允许实施项目使用旧约定或新约定来配置此启动器...
另一个更新...
我一直在使用 SpEL 表达式,当属性存在和不存在时,条件检查都有效,但事后我遇到了属性解析问题。我认为问题在于属性默认值和复杂的 SpEL 表达式不能很好地结合在一起。
@Value("#{${com.mycompany.propertygroup.propertyname:null} != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}")
private String myProperty;
当我的 SpEL 像上面那样编写时,我得到一个无法解析属性占位符异常,这意味着必须存在两个属性才能使 SpEL 表达式进行评估。所以我开始思考,我可以使用我见过的用于解析可选属性的默认属性语法:@Value("${myoptionalproperty:defaultValue}")
所以下面是我尝试将默认属性解析与 SpEL 表达式结合起来:
@Value("#{${com.mycompany.propertygroup.propertyname:null} != null ? '${com.mycompany.propertygroup.propertyname:}' : '${oldconvention.propertyname:}'}")
private String myProperty;
使用默认属性表示法时,我不断收到此错误:
org.springframework.expression.spel.SpelParseException:
EL1041E: After parsing a valid expression, there is still more data in the expression: 'colon(:)'
当我用谷歌搜索该错误时,流行的答案是属性必须用单引号括起来,以便它们评估为字符串......但它们已经被包装了(除了第一个......我不得不解包那是因为我希望将其评估为空值检查的文字空值)。所以我认为当它们被包装在一个拼写表达式中时,默认值不能与属性一起使用。事实上,我只在@Value 注释仅使用纯属性持有者设置时见过默认属性集,而我在 SpEL 表达式中看到的所有属性都没有默认集。
【问题讨论】:
-
假设可以做到这一点,如果用户同时拥有旧约定和新约定会发生什么?
-
@pvpkiran ,在这种情况下,我会赞成新的约定而不是旧的约定。
-
下面的方法你可以做到。数组值:[“A”, “B”, “C”] @Value("${listOfValues}") private String[] valuesArray;
-
baeldung.com/spring-value-annotation --> 参见 spring 文档
-
@Value("${com.mycompany.propertygroup.propertyname:${oldconvention.property}}")应该可以解决问题。
标签: java spring spring-boot properties