1.目的:现在几乎所有项目都有定时任务所以呢我也来整一下哈,感觉应该是每个人要掌握的小知识。
2.使用环境:在springboot下数据库时mysql,需要这个类quartz即可。
3.引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.1</version> </dependency>
4.首先想下我们要干哈,方便后续操作,很明显需要把每个定时任务写入数据库,然后读取数据库的数据,这样也好控制定时任务的开关。建立表
DROP TABLE IF EXISTS `schedule_task`;
CREATE TABLE `schedule_task` (
`id` bigint(20) NOT NULL,
`task_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '定时任务名称',
`task_cron` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '定时时间',
`task_desc` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '任务描述',
`bean_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '类名',
`task_stauts` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '1-启用,0-停用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
同时反向生成实体类
5.代码实现
最关键的工具类`
package com.example.demo.task;
import com.example.demo.enetity.ScheduleTask;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class QuartzUtil {
@Autowired
Scheduler scheduler;
//用于增加任务
public Boolean add(ScheduleTask scheduleTask) {
try {
Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(scheduleTask.getBeanClass()).newInstance().getClass();
JobDetail jobBuilder = JobBuilder.newJob(jobClass).withIdentity(scheduleTask.getTaskName(), scheduleTask.getTaskName()).build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(scheduleTask.getTaskName(), scheduleTask.getTaskName()).startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(scheduleTask.getTaskCron())).startNow().build();
scheduler.scheduleJob(jobBuilder,trigger);
if(!scheduler.isShutdown()){
scheduler.start();
}
System.out.println(scheduleTask.getTaskDesc()+"任务成功");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//用于删除任务
public Boolean delete(ScheduleTask scheduleTask){
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleTask.getTaskName(),
scheduleTask.getTaskName());
try {
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
// 删除任务
scheduler.deleteJob(JobKey.jobKey( scheduleTask.getTaskName(), scheduleTask.getTaskName()));
return true;
} catch (SchedulerException e) {
return false;
}
}
//用于关闭定时任务
public Boolean shutdownJobs() {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
return true;
} catch (SchedulerException e) {
e.printStackTrace();
return false;
}
}
}
b.增加监听器,确保每次启动项目会初始化定时任务
package com.example.demo.task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(value = 1)
public class TaskInitListener implements CommandLineRunner {
@Autowired
TaskService taskService;
@Override
public void run(String... args) throws Exception {
taskService.initShedule();
}
}
c,cotroller层
package com.example.demo.task;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@CrossOrigin
@RestController
@RequestMapping("/task")
public class TaskController {
@Autowired
private TaskService taskService;
@PostMapping("/start/task")
public ResponseBean start(@RequestBody JSONObject jsonObject){
return taskService.addTask(jsonObject);
}
@PostMapping("/stop/task")
public ResponseBean stop(@RequestBody JSONObject jsonObject){
return taskService.stopTask(jsonObject);
}
@GetMapping("/stopAll/task")
public ResponseBean stopAll(){
return taskService.stopTaskAll();
}
@GetMapping("/init/task")
public ResponseBean initTak(){
return taskService.initShedule();
}
@GetMapping("/deleteAll/task")
public ResponseBean deleteAll(){
return taskService.deleteAll();
}
}
d.service层和实现
package com.example.demo.task;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
public interface TaskService {
ResponseBean initShedule();
ResponseBean addTask(JSONObject jsonObject);
ResponseBean stopTask(JSONObject jsonObject);
ResponseBean deleteAll();
ResponseBean stopTaskAll();
}
package com.example.demo.task;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.dao.ScheduleTaskMapper;
import com.example.demo.enetity.ResponseBean;
import com.example.demo.enetity.ScheduleTask;
import com.example.demo.util.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class TaskServiceImpl implements TaskService {
@Autowired
private ScheduleTaskMapper scheduleTaskMapper;
@Autowired
QuartzUtil quartzUtil;
@Override
public ResponseBean initShedule() {
System.out.println("初始化init");
List<ScheduleTask> scheduleTasks = scheduleTaskMapper.selectAll();
ArrayList arrayList = new ArrayList();
for (int i = 0; i < scheduleTasks.size(); i++) {
if ("1".equals(scheduleTasks.get(i).getTaskStauts())) {
Boolean add = quartzUtil.add(scheduleTasks.get(i));
if (!add) {
//出现问题回退之前的定时任务
JSONObject jsonObject = new JSONObject();
jsonObject.put("taskName", arrayList);
stopTask(jsonObject);
return null;
}
arrayList.add(scheduleTasks.get(i).getTaskName());
}
}
return null;
}
@Override
public ResponseBean addTask(JSONObject jsonObject) {
JSONArray taskName = jsonObject.getJSONArray("taskName");
List<ScheduleTask> scheduleTasks = scheduleTaskMapper.selectByTaskList(taskName);
for (int i = 0; i < scheduleTasks.size(); i++) {
quartzUtil.add(scheduleTasks.get(i));
}
return CommonUtils.succssonJson();
}
@Override
public ResponseBean stopTask(JSONObject jsonObject) {
JSONArray taskName = jsonObject.getJSONArray("taskName");
List list = new ArrayList<>();
for (int i = 0; i < taskName.size(); i++) {
list.add(taskName.getString(i));
}
if (list.size() > 0) {
List<ScheduleTask> scheduleTasks = scheduleTaskMapper.selectByTaskList(list);
for (int i = 0; i < scheduleTasks.size(); i++) {
if (!quartzUtil.delete(scheduleTasks.get(i))) {
System.out.println(scheduleTasks.get(i).getTaskName() + "有误");
}
}
}
return CommonUtils.succssonJson();
}
@Override
public ResponseBean deleteAll() {
List<ScheduleTask> scheduleTasks = scheduleTaskMapper.selectAll();
ArrayList arrayList = new ArrayList();
for (int i = 0; i < scheduleTasks.size(); i++) {
if ("1".equals(scheduleTasks.get(i).getTaskStauts())) {
arrayList.add(scheduleTasks.get(i).getTaskName());
}
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("taskName", arrayList);
stopTask(jsonObject);
return null;
}
@Override
public ResponseBean stopTaskAll() {
if (quartzUtil.shutdownJobs()) {
return CommonUtils.succssonJson();
} else {
return null;
}
}
}
e.返回类
package com.example.demo.enetity;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.util.ErrorEnum;
public class ResponseBean {
private String retCode;
private String retMsg;
private JSONObject result;
public ResponseBean(){
}
public ResponseBean(String retCode, String retMsg, JSONObject result) {
this.retCode = retCode;
this.retMsg = retMsg;
this.result = result;
}
public ResponseBean(String retCode, String retMsg) {
this.retCode = retCode;
this.retMsg = retMsg;
}
public ResponseBean(ErrorEnum errorEnum) {
this.retCode = errorEnum.getErrorCode();
this.retMsg = errorEnum.getErrorMsg();
this.result = new JSONObject();
}
public String getRetCode() {
return retCode;
}
public String getRetMsg() {
return retMsg;
}
public void setRetMsg(String retMsg) {
this.retMsg = retMsg;
}
public JSONObject getResult() {
return result;
}
public void setResult(JSONObject result) {
this.result = result;
}
public void setRetCode(String retCode) {
this.retCode = retCode;
}
}
f.到这一步其实就已经写好了定时任务框架,接下来就是和数据的关联以及测试。
3.建立目录如下
a.定时任务
1.造车
package com.example.demo.task.taskName;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class carTask implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("造车定时任务");
}
}
2.睡觉定时任务
package com.example.demo.task.taskName;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class sleepTask implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("睡觉定时任务");
}
}
3.微笑定时任务
package com.example.demo.task.taskName;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class smileTask implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("微笑定时任务");
}
}
4.在数据库里这样配置
5.然后启动项目就可以发现定时任务在跑了。