gpt4 book ai didi

java - 使用来自 yaml 文件的多个 cron 表达式的 Spring-Boot 一个 @Scheduled 任务

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:36:48 24 4
gpt4 key购买 nike

我喜欢使用 .yml 文件的不同配置属性来实现一个 @Scheduled 作业。

在我的 yaml 文件中,我将 cron 表达式 描述为一个列表:

job:
schedules:
- 10 * * * * *
- 20 * * * * *

我使用 Configuration 读出这些值并创建了一个名为 scheduled@Bean:

@Configuration
@ConfigurationProperties(prefix="job", locations = "classpath:cronjob.yml")
public class CronConfig {

private List<String> schedules;

@Bean
public List<String> schedules() {
return this.schedules;
}

public List<String> getSchedules() {
return schedules;
}

public void setSchedules(List<String> schedules) {
this.schedules = schedules;
}
}

在我的 Job 类中,我想开始执行一个方法,但对于我的配置中的两个计划。

 @Scheduled(cron = "#{@schedules}")
public String execute() {
System.out.println(converterService.test());
return "success";
}

使用此解决方案,应用程序会产生错误:(或多或少清楚)

Encountered invalid @Scheduled method 'execute': Cron expression must consist of 6 fields (found 12 in "[10 * * * * *, 20 * * * * *]")

有没有办法用多个 cron 表达式声明来配置相同的计划作业方法?


编辑 1

经过一些尝试,我在执行器方法上使用了第二个注解。

@Scheduled(cron = "#{@schedules[0]}")
@Scheduled(cron = "#{@schedules[1]}")
public String execute() {
System.out.println(converterService.test());
return "success";
}

此解决方案有效但不是真正动态的。还有一种方法可以使其动态化吗?

最佳答案

(编辑,因为我找到了执行此操作的方法)

您实际上可以做到这一点。下面我展示了一个工作示例:

cronjob.yaml

job:
schedules:
- 10 * * * * *
- 20 * * * * *

执行MyTask的实际任务:

package hello;

import org.springframework.stereotype.Component;

@Component
public class MyTask implements Runnable {

@Override
public void run() {
//complicated stuff
}
}

你的 CronConfig 是:

package hello;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
@ConfigurationProperties(prefix="job", locations = "classpath:cronjob.yml")
public class CronConfig {

private List<String> schedules;

@Bean
public List<String> schedules() {
return this.schedules;
}

public List<String> getSchedules() {
return schedules;
}

public void setSchedules(List<String> schedules) {
this.schedules = schedules;
}
}

负责安排所有 crons 的 ScheduledTask bean:

package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

@Autowired
private TaskScheduler taskScheduler;

@Autowired
private CronConfig cronConfig;

@Autowired
private MyTask myTask;

private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);

public void scheduleAllCrons() {

cronConfig.getSchedules().forEach( cron -> taskScheduler.schedule(myTask, new CronTrigger(cron)) );
}
}

上下文/主类Application:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application {

@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}


public static void main(String[] args) throws Exception {
ApplicationContext ctx = SpringApplication.run(Application.class);

ScheduledTasks scheduledTasks = ctx.getBean(ScheduledTasks.class);

scheduledTasks.scheduleAllCrons();
}
}

关于java - 使用来自 yaml 文件的多个 cron 表达式的 Spring-Boot 一个 @Scheduled 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40929161/

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