The background,
At work, sometimes the execution of some scheduled tasks needs to be dynamically modified, for example: Generating reports, some projects are configured to generate reports at 8 o ‘clock every day, some projects are configured to generate reports at 10 o ‘clock every day, such dynamic Task execution times, without considering distributed execution, can be easily implemented using Spring Task.
Second, requirements and implementation ideas
1, can dynamically add a scheduled task.
inSpring
A class exists inThreadPoolTaskScheduler
, it can be implemented according to aCron expression
To schedule a task and return aScheduledFuture
Object.
2. Cancel scheduled tasks.
This task can be cancelled by calling the Cancel method of the ScheduledFuture from the previous step.
3. Dynamically change the execution time of a task.
- Cancel the task first.
- Then re-register a task.
4. Obtain the scheduled task execution exception
There is a setting in the ThreadPoolTaskScheduler classErrorHandler
ErrorHandler can be implemented to their own method.
Tip:
-
Scheduled tasks that are implemented in Spring via the @scheduled annotation are also implemented at the bottom via ThreadPoolTaskScheduler. Can pass ScheduledAnnotationBeanPostProcessor class to look at it.
-
The default number of threads on the ThreadPoolTaskScheduler scheduler is 1.
Three, code implementation
This section provides only the codes for dynamically registering scheduled tasks and canceling scheduled tasks.
package com.huan.study.task.jobs.tasks;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/ * * *@authorHuan.fu 2021/7/8-2:46 PM */
@Component
@Slf4j
public class DynamicCronTask implements InitializingBean {
@Autowired
private ThreadPoolTaskScheduler taskScheduler;
privateScheduledFuture<? > scheduledFuture;@Override
public void afterPropertiesSet(a) throws Exception {
// Dynamically start a scheduled task
log.info("Register a scheduled task: Execute it every second.");
scheduledFuture = register("* * * * *?");
// Cancel a schedule
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
log.info("Cancel the dispatch");
scheduledFuture.cancel(false);
log.info("Cancellation result :" + scheduledFuture.isCancelled());
log.info("Re-register a scheduled task: Every 2 seconds");
register("*/2 * * * *?");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
privateScheduledFuture<? > register(String cron) {// Older versions use CronExpression and younger versions use CronSequenceGenerator
boolean validExpression = CronExpression.isValidExpression(cron);
log.info("Cron :[{}] is legal :[{}]", cron, validExpression);
CronExpression expression = CronExpression.parse(cron);
LocalDateTime nextExecTime = expression.next(LocalDateTime.now());
if (null! = nextExecTime) { log.info("The next execution time of the scheduled task is :[{}]", nextExecTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
return taskScheduler.schedule(new Runnable() {
@Override
public void run(a) {
log.info("I did it."); }},newCronTrigger(cron)); }}Copy the code
4. Execution results
Complete code
Gitee.com/huan1993/sp…