如何使用Spring Expression Language处理多个后备值

问题描述 投票:1回答:1

问题是:我该如何处理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不幸的是,这不是我想要的!

java spring spring-el
1个回答
0
投票

我发现了两种解决方法:

第一个,纯粹基于Spring表达式。如果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表达式语言可以处理多个后备。是应该使用它,还是更易读的配置方法...我让您决定。

© www.soinside.com 2019 - 2024. All rights reserved.