Spring boot:如何参数化@Scheduled

use*_*500 5 java spring-boot

我是 Spring 的新手,只触及了 Spring 的皮毛。

我遇到一种情况,需要使用@Scheduled注释设置重复任务。速率被指定为对象中的成员字段,该对象被传递给封装表示任务的方法的类。

我使用了允许访问配置或环境的机制,例如@Scheduled(fixedRateString = "${some.property:default}");这很好用。

我不知道该怎么做是将对象中的值插入到@Scheduled.

例如:

class MyClass {
  private MyObject myObj;

  public MyClass(MyObject myObj) {
    this.myObj = myObj;
  }

  @Scheduled(fixedRateString = "${myObj.rate:5000}")
  private void someTask() {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,上面的代码不起作用,我只是给出了我想要做的事情的例子。

任何建议,将不胜感激。

And*_*own 7

是的,您可以使用@Scheduled注释通过 SpEL 表达式来执行此操作(@Scheduled自 Spring 4.3.x 起可在注释上使用)。这是一个例子:

@Slf4j
@Configuration
@EnableScheduling
public class ExampleClass {

  static class ScheduleCalculator {
    public String calc() {
      return "5000";
    }
  }

  @Bean("scheduleCalculator")
  public ScheduleCalculator createScheduleCalculator() {
    return new ScheduleCalculator();
  }

  @Scheduled(fixedRateString = "#{scheduleCalculator.calc()}")
  public void someTask() {
    log.info("Hello world");
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,仅仅因为您可以这样做并不意味着您一定应该这样做。

如果您使用Spring 任务调度程序,并且您可以控制用于调度的线程池,而不是依赖于所有@Scheduled任务都集中到的共享执行器,那么您的代码可能会更容易被将来必须维护它的人们所理解。


小智 5

不幸的是,Spring bean 创建过程不会读取这样的局部变量。

您可以使用 Spring TaskScheduler 类。

本质上,您只需定义一个线程池,用于运行计划任务(作为 bean)并运行 taskScheduler.schedule(runnable, new CronTrigger("* * * * *"))。这里有一个详细的例子:

https://www.baeldung.com/spring-task-scheduler