java - 如何在 Spring 表达式语言中处理多个后备值
问题描述
问题是:如何处理 Spring 表达式中的一串后备值,允许我在获得定义值之前回退到更高级别的配置?
为了稍微解释一下,让我们用我自己的用例来说明这一点:我打算使用@Scheduled
注释创建一个 Spring 应用程序来运行一些进程。事情是我有很多计划任务,我会让运行频率可以轻松地为所有这些任务配置,或者只为一个子集配置。
所以我一直在寻找类似的东西
@Component
public class SpecificTaskRunner {
@Scheduled(cron = "${ specific-task-cron ?: task-families-cron ?: default-cron }")
public void specificTask() {
doSomething();
}
}
让应用程序通过覆盖值一次配置所有计划任务的频率default-cron
,或者通过覆盖任务族属性仅配置其中的一个子集,或者最后在任务的基础上进行指定。这种方法的优点是它允许使用多个配置级别,因为每个计划任务从最具体的开始寻找适当的属性,并寻找更通用的属性直到它得到定义,最终回退到默认的全局值.
不幸的是......这不起作用。评估时,如果未定义第一个元素,则如果回退整个剩余元素。在此示例中,这意味着如果配置缺少 的值specific-task-cron
,则解析的值是 :task-families-cron ?: default-cron
不幸的是,这不是我想要的!
解决方案
我找到了两种处理方法:
第一个,纯粹是基于Spring的表达方式。如果它也是一个 Spring 表达式,那么 Spring 似乎会重新评估 Elvis 运算符的结果。所以我的工作配置是:
@Component
public class SpecificTaskRunner {
@Scheduled(cron = "${ specific-task-cron ?: ${ task-families-cron ?: default-cron }}")
public void specificTask() {
doSomething();
}
}
在我的实际用例中,再加上一个后备,并不是很方便......
所以我切换到一个更简单的解决方案,它通过这种方式定义一个值链来依赖配置:
#application.yml
default-cron: '0 */5 0 0 0 0' #every 5 minutes
task-families-cron: ${default-cron}
specific-task-cron: ${task-families-cron}
结合
@Component
public class SpecificTaskRunner {
@Scheduled(cron = "${specific-task-cron}")
public void specificTask() {
doSomething();
}
}
这样,任何对属性的覆盖都适用于分层子级别,除非它们自己被覆盖。
这两种解决方案似乎都有效,所以最后,是的 Spring 表达式语言处理多个回退。是否应该使用,或者配置方法更具可读性......我让你决定。
推荐阅读
- javascript - Ng-If 仅在刷新页面时工作
- reactjs - redux 与 antd 表单验证如何集成
- sql - 如何根据第一个最小到最大,数字后跟Alpha对sql server结果进行排序
- solr - solr-7.6.0 忽略配置文件 bin/solr.in.sh
- scala - 配置 Spark 作业以将 3000000 文件作为输出写入
- spring-boot - 如何从 Jenkins 的 Jacoco 代码覆盖范围中排除构建器类?
- javascript - 使用 svg.draw.js 绘制多个矩形
- mysql - SailsJS: How to define a custom type attribute for a Model without creating a new relationship
- excel - Excel VBA尝试使用For-Loop向具有不同范围的单元格写入“MAX”公式
- django - Django migrations - Get current app name in RunPython function