gpt4 book ai didi

java - 如何在 Spring 使用 EnableScheduling 注释在运行时重新启动计划任务?

转载 作者:IT老高 更新时间:2023-10-28 13:57:46 24 4
gpt4 key购买 nike

我一直在研究如何使用 Java 8 和 spring 在运行时更改作业的频率。 This question非常有用,但并没有完全解决我的问题。

我现在可以配置下一次执行作业的日期。但是如果将延迟设置为 1 年,那么我需要等待 1 年才能考虑到新配置。

我的想法是如果配置值发生更改(因此来自另一个类),则停止计划任务。然后重新计算下一次应该执行的任务。也许有更简单的方法来做到这一点。

这是我目前的代码。

@Configuration
@EnableScheduling
public class RequestSchedulerConfig implements SchedulingConfigurer {

@Autowired
SchedulerConfigService schedulerConfigService;

@Bean
public RequestScheduler myBean() {
return new RequestScheduler();
}

@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
taskRegistrar.addTriggerTask(
new Runnable() {
@Override public void run() {
myBean().startReplenishmentComputation();
}
},
new Trigger() {
@Override public Date nextExecutionTime(TriggerContext triggerContext) {
Duration d = schedulerConfigService.getIntervalFromDB();
return DateTime.now().plus(d).toDate();
}
}
);
}
}

这就是我想做的。

@RestController
@RequestMapping("/api/config/scheduler")
public class RequestSchedulerController {

@Autowired
ApplicationConfigWrapper applicationConfigWrapper;

@RequestMapping("/set/")
@ResponseBody
public String setRequestSchedulerConfig(@RequestParam(value = "frequency", defaultValue = "") final String frequencyInSeconds){
changeValueInDb(frequencyInSeconds);
myJob.restart();
return "Yeah";
}

}

最佳答案

  1. 创建一个获得注入(inject)的单例 bean TaskScheduler .这将作为状态变量保存所有 ScheduledFutures ,例如 private ScheduledFuture job1;
  2. 在部署时,从数据库加载所有计划数据并启 Action 业,填写所有状态变量,如 job1
  3. 关于调度数据的变化,cancel对应的Future(例如job1),然后用新的调度数据重新开始。

这里的关键思想是在创建 Future 时对其进行控制,以便将它们保存在一些状态变量中,这样当调度数据中的某些内容发生变化时,您可以取消它们。

这是工作代码:

applicationContext.xml

<task:annotation-driven />
<task:scheduler id="infScheduler" pool-size="10"/>

持有 Futures

的单例 bean
@Component
public class SchedulerServiceImpl implements SchedulerService {

private static final Logger logger = LoggerFactory.getLogger(SchedulerServiceImpl.class);

@Autowired
@Qualifier(value="infScheduler")
private TaskScheduler taskScheduler;

@Autowired
private MyService myService;

private ScheduledFuture job1;//for other jobs you can add new private state variables

//Call this on deployment from the ScheduleDataRepository and everytime when schedule data changes.
@Override
public synchronized void scheduleJob(int jobNr, long newRate) {//you are free to change/add new scheduling data, but suppose for now you only want to change the rate
if (jobNr == 1) {//instead of if/else you could use a map with all job data
if (job1 != null) {//job was already scheduled, we have to cancel it
job1.cancel(true);
}
//reschedule the same method with a new rate
job1 = taskScheduler.scheduleAtFixedRate(new ScheduledMethodRunnable(myService, "methodInMyServiceToReschedule"), newRate);
}
}
}

关于java - 如何在 Spring 使用 EnableScheduling 注释在运行时重新启动计划任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31969251/

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