spring简单集成定时任务
直接使用
@EnableScheduling
开启定时任务,使用@Scheduled(cron = "")
来标注任务马上就可以完成一个简单的定时任务了,这里就不贴上代码了
spring动态实现定时任务
创建一个
SchedulingConfig
配置类来初始化定时任务的线程池的大小和名称等信息
// 开启定时任务
@EnableScheduling
@Configuration
public class SchedulingConfig {
@Bean
public TaskScheduler taskScheduler() {
// 创建任务调度线程池
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
// 初始化线程池数量
taskScheduler.setPoolSize(4);
// 是否将取消后的任务,从队列中删除
taskScheduler.setRemoveOnCancelPolicy(true);
// 设置线程名前缀
taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");
return taskScheduler;
}
}
查找代码可以看见sringbot中有相关的定时任务注册类,需要实现
SchedulingConfigurer
类来进行注册定时任务,configureTasks
在项目初始化的时候会进行执行然后通ScheduledTaskRegistrar
用来注册定时任务,这里想进行动态的增加不太现实,我们可以对这个类做一个改变使我们可以在项目启动之后获取到ScheduledTaskRegistrar
这个类,代码如下:
@Component
public class ReportAutoTask implements SchedulingConfigurer {
private ScheduledTaskRegistrar scheduledTaskRegistrar;
/**
* 根据taskId来储存指定的任务
*/
private Map<String, ScheduledTask> scheduledTaskMap = new ConcurrentHashMap<>(16);
/**
* 定时任务注册(这个方法会在启动的时候进行执行)
*
* @param scheduledTaskRegistrar
*/
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
this.scheduledTaskRegistrar = scheduledTaskRegistrar;
}
public ScheduledTaskRegistrar getScheduledTaskRegistrar() {
return scheduledTaskRegistrar;
}
public void setScheduledTaskRegistrar(ScheduledTaskRegistrar scheduledTaskRegistrar) {
this.scheduledTaskRegistrar = scheduledTaskRegistrar;
}
public Map<String, ScheduledTask> getScheduledTaskMap() {
return scheduledTaskMap;
}
public void setScheduledTaskMap(Map<String, ScheduledTask> scheduledTaskMap) {
this.scheduledTaskMap = scheduledTaskMap;
}
}
使用ScheduledTaskRegistrar来注册定时任务
红色的是这个类新增定时任务的方法,这里主要是用
addCronTask
这个方法来新增定时任务
可以看到addCronTask上图中需要一个
Runnable
和一个表达式的参数,这两个参数也是创建一个CronTask的要求,所以我们首先去创建一个Runnable
,代码中是我自己创建的一些业务可以忽略,主要的方法就是一个run
方法
@Component
@Slf4j
public class ReportAutoRunnable implements Runnable {
/**
* reportAutoDTO
*/
private ReportAutoDTO reportAutoDTO;
public ReportAutoDTO getReportAutoDTO() {
return reportAutoDTO;
}
public void setReportAutoDTO(ReportAutoDTO reportAutoDTO) {
this.reportAutoDTO = reportAutoDTO;
}
@Autowired
private ReportAutoService reportAutoService;
@Override
public void run() {
String name = Thread.currentThread().getName();
try {
log.info("定时任务开始执行 任务id:{} ,线程名称:{}", reportAutoDTO.getId(),name);
reportAutoService.autoReport(reportAutoDTO);
log.info("定时任务执行完毕 任务id:{} ,线程名称:{}", reportAutoDTO.getId(),name);
} catch (Exception ex) {
log.info("定时任务执行出现异常 任务id:{} ,异常信息:{}", reportAutoDTO.getId(),ex.getMessage());
}
}
}
自定义CronTask
创建完Runnable后可以创建一个
CronTask
,我是继承了一下CronTask类增加了两个属性一个id,一个名称
public class ReportAutoCronTask extends CronTask {
/**
* 任务id
*/
private String taskId;
/**
* 任务名称
*/
private String taskName;
public ReportAutoCronTask(Runnable runnable, String expression) {
super(runnable, expression);
}
public ReportAutoCronTask(Runnable runnable, CronTrigger cronTrigger) {
super(runnable, cronTrigger);
}
public ReportAutoCronTask(Runnable runnable, String expression,String taskId,String taskName){
super(runnable, expression);
this.taskId = taskId;
this.taskName = taskName;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
}
注册并启动定时任务
下面这一块代码就可以成功的注册一个定时任务
// 每30秒执行一次
String expression ="0/30 0 0 * ?";
// 创建定时任务
ReportAutoCronTask reportAutoCronTask = new ReportAutoCronTask(reportAutoRunnable, expression, "1111", "任务名称");
scheduledTaskRegistrar.addCronTask(reportAutoCronTask);
// 启动定时任务
ScheduledTask scheduledTask = scheduledTaskRegistrar.scheduleCronTask(reportAutoCronTask);reportAutoCronTask.setFlag(true);
scheduledTaskMap.put("1111", scheduledTask);
关闭指定的定时任务
遍历之前储存任务的集合直接调用
cancel()
就可以直接关闭带任务,如果需要删除的话就直接删除掉map中的定时任务就可以,想修改可以删除掉再重新新增
for (Map.Entry<String, ScheduledTask> scheduledTaskEntry : scheduledTaskMap.entrySet()) {
if (scheduledTaskEntry.getKey().equals(reportAutoDTO.getId())) {
// 停止定时任务
scheduledTaskEntry.getValue().cancel();
}
}