gpt4 book ai didi

java - Spring @Value 注解中可以指定多个属性名称吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:49:40 25 4
gpt4 key购买 nike

我已经熟悉 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的属性(property)
oldconvention.property=value

B项目属性(property)
com.mycompany.propertygroup.propertyname=value

我似乎找不到关于这是否可行以及如何实现它的任何文档或 SO 答案……所以我想知道是否可行,或者如果不可行,是否有替代方案 @Value可以用来达到相同效果的注解?

编辑澄清:
我不想跟踪多个值,所以我不需要关于如何获取多个值的说明......目标是合并成一个 单值可能有多个名字的那个。在实践中,每个使用 starter 的项目只会有一个名称值……只有在极少数情况下,当有人可能忘记删除旧属性时,才会使用每个属性名称(无论如何它可能具有相同的值)。在这种情况下,新的公约名称-值应该是 一个使用。

更新

虽然当两个属性都存在时提供的 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 表达式中看到的所有属性从未设置过默认值。

最佳答案

您可以使用以下 @Value注解:

@Configuration
public class MyConfig {

@Value("#{'${com.mycompany.propertygroup.propertyname:${oldconvention.propertyname:}}'}")
private String myValue;
}

@Value注释使用 com.mycompany.propertygroup.propertyname如果提供并默认为 oldconvention.property如果 com.mycompany.propertygroup.propertyname不提供。如果两者均未提供,则该属性设置为 null .您可以通过替换 null 将此默认值设置为另一个值。具有另一个所需的值。

有关更多信息,请参阅以下内容:
  • Spring Expression Language (SpEL)
  • Spring Expression Language Guide


  • 作为替代方案,您可以捕获两个值并在返回值之前进行选择:
    @Configuration
    public class MyConfig {

    @Value("${com.mycompany.propertygroup.propertyname:}")
    private String newValue;

    @Value("${oldconvention.propertyname:}")
    private String oldValue;

    public String getValue() {

    if (newValue != null && !newValue.isEmpty()) {
    // New value is provided
    System.out.println("New Value: " + newValue);
    return newValue;
    }
    else {
    // Default to the old value
    return oldValue;
    }
    }
    }

    关于java - Spring @Value 注解中可以指定多个属性名称吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49653241/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com