ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 Spring 3.0 表达式语言参数化 @Scheduled(fixedDelay)?

当使用 Spring 3.0 功能注释计划任务时,我想将 fixedDelay 设置为我的配置文件中的参数,而不是像现在这样将它硬连接到我的任务类中......

@Scheduled(fixedDelay = 5000)
public void readLog() {
        ...
}

不幸的是,似乎使用 Spring 表达式语言 (SpEL) @Value 返回一个 String 对象,而该对象又不能按照 fixedDelay 参数的要求自动装箱为 long 值。


M
Mark-A

Spring v3.2.2 在原来的 3 个 long 参数中添加了 String 参数来处理这个问题。 fixedDelayStringfixedRateStringinitialDelayString 现在也可用。

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}

@Avi这个答案是在OP提出问题三年后提出的。在提出问题(和接受的答案)时,此功能不存在。
@medveshonok117 知道了。谢谢
@medveshonok117 和?现在仍然是最正确的答案。
k
kan

您可以使用 @Scheduled 注释,但只能与 cron 参数一起使用:

@Scheduled(cron = "${yourConfiguration.cronExpression}")

您的 5 秒间隔可以表示为 "*/5 * * * * *"。但是,据我了解,您不能提供少于 1 秒的精度。


您显示的 cron 表达式等效于 fixedRate,与 fixedDelay 不同
G
Grzegorz Oledzki

我猜 @Scheduled 注释是没有问题的。因此,也许您的解决方案是使用 task-scheduled XML 配置。让我们考虑这个例子(从 Spring doc 复制):

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="someObject" method="readLog" 
               fixed-rate="#{YourConfigurationBean.stringValue}"/>
</task:scheduled-tasks>

...或者如果从 String 到 Long 的演员表不起作用,这样的事情会:

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="someObject" method="readLog"
            fixed-rate="#{T(java.lang.Long).valueOf(YourConfigurationBean.stringValue)}"/>
</task:scheduled-tasks>

同样,我还没有尝试过任何这些设置,但我希望它可以帮助你一点。


谢谢,XML 配置成功了。我有点惊讶注释似乎与字符串值如此绑定,无论如何,我采用老式的方式;-)
上述配置是否有任何 Java 等效项?
@Grzegorz Oledzki 标签下的“someObject”的值是什么。如果控制器有不止一种方法需要固定延迟和初始延迟,那么将如何处理?
a
attacomsian

在 Spring Boot 2 中,我们可以将 Spring 表达式语言 (SpPL) 用于 @Scheduled 注释属性:

@Scheduled(fixedRateString = "${fixed-rate.in.milliseconds}")
public void fixedRate() {
    // do something here
}

@Scheduled(fixedDelayString = "${fixed-delay.in.milliseconds}")
public void fixedDelay() {
    // do something here
}

@Scheduled(cron = "${cron.expression}")
public void cronExpression() {
    // do something here
}

application.properties 文件如下所示:

fixed-rate.in.milliseconds=5000
fixed-delay.in.milliseconds=4000
cron.expression=0 15 5 * * FRI

而已。这里是an article,它详细解释了任务调度。


G
Grzegorz Oledzki

我猜你可以通过定义一个bean来自己转换值。我没有尝试过,但我想类似于以下的方法可能对你有用:

<bean id="FixedDelayLongValue" class="java.lang.Long"
      factory-method="valueOf">
    <constructor-arg value="#{YourConfigurationBean.stringValue}"/>
</bean>

在哪里:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>

谢谢,这听起来像是一种方式,但老实说,我希望有一个更优雅(“弹性”)的解决方案:-)
不幸的是,这不起作用,因为 @Scheduled 注释属性 fixedDelay 需要分配一个(长)常量。
啊,没错。所以我猜你不能用 @Scheduled 注释来做到这一点。