包含两种方式
一、方法一 ,复杂一点,但是可以保证设置完实时生效
/**
* 向springIOC中注入一个定时任务线程池备用
* @author WXM
* @date 2022/07/19
*/
@Configuration
public class ScheduledConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(3);
threadPoolTaskScheduler.setRemoveOnCancelPolicy(true);
return threadPoolTaskScheduler;
}
}
/**
* 自定义一个实体类方便存储任务参数
* @author WXM
* @date 2022/07/19
*/
public class ScheduledFutureHolder {
private ScheduledFuture<?> scheduledFuture;
private Runnable task;
private String corn;
public ScheduledFuture<?> getScheduledFuture() {
return scheduledFuture;
}
public void setScheduledFuture(ScheduledFuture<?> scheduledFuture) {
this.scheduledFuture = scheduledFuture;
}
public String getCorn() {
return corn;
}
public void setCorn(String corn) {
this.corn = corn;
}
public Runnable getTask() {
return task;
}
public void setTask(Runnable task) {
this.task = task;
}
@Override
public String toString() {
return "ScheduledFutureHolder{" +
"scheduledFuture=" + scheduledFuture +
", task=" + task +
", corn='" + corn + '\'' +
'}';
}
}
/**
* 具体任务执行代码,可以根据业务场景定义多个
* @author WXM
* @date 2022/07/19
*/
public class DatabaseBackupTask implements Runnable {
@Override
public void run() {
System.out.println(new Date()+"定时任务执行............");
}
}
@Component
public class ScheduleUtil {
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
//存储任务执行的包装类
private HashMap<String, ScheduledFutureHolder> scheduleMap = new HashMap<>();
/**
*启动任务
* 如果不想手动触发任务可以使用 @PostConstruct注解来启动
*/
public void startTask(Runnable task, String cron) {
String taskName = task.getClass().getName();
try {
// 判断当前任务是否已经在计划列表,在的话不再重复加载
if (scheduleMap.containsKey(taskName)) {
logger.info("当前任务已存在,不再重复加载。如需修改任务执行间隔,请调用restart接口");
return;
}
// 将任务交给任务调度器执行
ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(task, new CronTrigger(cron));
// 将任务包装成ScheduledFutureHolder
ScheduledFutureHolder scheduledFutureHolder = new ScheduledFutureHolder();
scheduledFutureHolder.setScheduledFuture(schedule);
scheduledFutureHolder.setTask(task);
scheduledFutureHolder.setCorn(cron);
scheduleMap.put(scheduledFutureHolder.getTask().getClass().getName(), scheduledFutureHolder);
logger.info("定时任务启动成功,任务名:[{}],cron:[{}]", taskName, cron);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查询所有的任务
*/
@RequestMapping("/queryTask")
public void queryTask(){
scheduleMap.forEach((k,v)->{
System.out.println(k+" "+v);
});
}
/**
* 停止任务
* @param className
*/
@RequestMapping("/stop/{className}")
public void stopTask(@PathVariable String className){
if(scheduleMap.containsKey(className)){//如果包含这个任务
ScheduledFuture<?> scheduledFuture = scheduleMap.get(className).getScheduledFuture();
if(scheduledFuture!=null){
scheduledFuture.cancel(true);
}
}
}
/**
* 重启任务,修改任务的触发时间
* @param className
* @throws InstantiationException
* @throws IllegalAccessException
*/
public void restartTask(String taskName, String cron) {
if (scheduleMap.containsKey(taskName)) {//如果包含这个任务
ScheduledFutureHolder scheduledFutureHolder = scheduleMap.get(taskName);
ScheduledFuture<?> scheduledFuture = scheduledFutureHolder.getScheduledFuture();
if (scheduledFuture != null) {
// 先停掉任务
scheduledFuture.cancel(true);
// 修改触发时间重新启动任务
Runnable runnable = scheduledFutureHolder.getTask();
ScheduledFuture<?> schedule = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(cron));
scheduledFutureHolder.setScheduledFuture(schedule);
scheduledFutureHolder.setCorn(cron);
scheduleMap.put(scheduledFutureHolder.getTask().getClass().getName(), scheduledFutureHolder);
logger.info("定时任务重新配置成功成功,任务名:[{}],cron:[{}]", taskName, cron);
}
}
}
}
二、方法二 ,代码相对简单,但是设置的cron只有在下次定时任务执行时才会触发(不能设置完实时触发)
/**
* @author WXM
* @date 2022/07/19
*/
@Lazy(false)
@Component
@EnableScheduling
public class SpringDynamicCornTask implements SchedulingConfigurer {
private static final Logger logger = LoggerFactory.getLogger(SpringDynamicCornTask.class);
private static String cron = "* * * 31 2 ?";
public SpringDynamicCornTask() {
}
public void setCron(String cron) {
this.cron = cron;
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(new Runnable() {
@Override
public void run() {
// 任务逻辑
logger.info("定时任务进行中...");
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
// 任务触发,可修改任务的执行周期
CronTrigger trigger = new CronTrigger(cron);
Date nextExecutionTime = trigger.nextExecutionTime(triggerContext);
return nextExecutionTime;
}
});
}
}
// controller层
@GetMapping ("changeScheduled")
public String changeScheduled(String cron){
springDynamicCornTask.setCron(cron);
return "suc";
}