org.springframework.boot
spring-boot-starter-quartz
org.springframework.boot
spring-boot-starter-web
org.quartz-scheduler
quartz
2.3.0
org.springframework
spring-context-support
5.3.8
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
org.projectlombok
lombok
@SpringBootApplication
@EnableScheduling
public class Quartz3Application {
public static void main(String[] args) {
SpringApplication.run(Quartz3Application.class, args);
}
}
package com.example.quartz3.job;
import java.util.*;
import javax.annotation.PostConstruct;
import lombok.extern.log4j.Log4j2;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* 调度service
*/
@Configuration
@EnableScheduling
@Log4j2
public class QuartzService {
@Autowired
private Scheduler scheduler;
@PostConstruct
public void startScheduler() {
try {
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 增加一个job
*
* @param jobClass 任务实现类
* @param jobName 任务名称
* @param jobGroupName 任务组名
* @param jobTime 时间表达式 (这是每隔多少秒为一次任务)
* @param jobTimes 运行的次数 (<0:表示不限次数)
*/
public void addJob(Class extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
int jobTimes) {
try {
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
.build();
// 使用simpleTrigger规则
Trigger trigger = null;
if (jobTimes < 0) {
trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
.startNow().build();
} else {
trigger = TriggerBuilder
.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
.startNow().build();
}
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 增加一个job
*
* @param jobClass 任务实现类
* @param jobName 任务名称
* @param jobGroupName 任务组名
* @param jobTime 时间表达式 (如:0/5 * * * * ? )
*/
public void addJob(Class extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime,Integer userId) {
try {
// 创建jobDetail实例,绑定Job实现类
// 指明job的名称,所在组的名称,以及绑定job类
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
.usingJobData("userId",userId)//可以使用usingJobData添加传入的参数,辅助后面job任务的业务实现
.build();
// 定义调度触发规则
// 使用cornTrigger规则
// 触发器key
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime).inTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))).startNow().build();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
if(!scheduler.isShutdown()){
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 修改 一个job的 时间表达式
*/
public void updateJob(String jobName, String jobGroupName, String jobTime) {
try {
log.warn("Start update job ,job name is {}, jobCron is {}", jobName, jobTime);
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime).inTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))).build();
// 重启触发器
scheduler.rescheduleJob(triggerKey, trigger);
log.warn("finish update job!");
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 删除任务一个job
*
* @param jobName 任务名称
* @param jobGroupName 任务组名
*/
public void deleteJob(String jobName, String jobGroupName) {
try {
scheduler.deleteJob(new JobKey(jobName, jobGroupName));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 暂停一个job
*
* @param jobName jobName
* @param jobGroupName jobName
*/
public void pauseJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复一个job
*
* @param jobName jobName
* @param jobGroupName jobGroupName
*/
public void resumeJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 立即执行一个job
*
* @param jobName jobName
* @param jobGroupName jobGroupName
*/
public void runAJobNow(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 获取所有计划中的任务列表
*
* @return List
*/
public List
package com.example.quartz3.job;
import com.example.quartz3.domain.User;
import com.example.quartz3.mapper.UserMapper;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 定时全量备份job
*/
@Component
@Log4j2
public class SomThingTimeJob extends QuartzJobBean {
@Autowired
private UserMapper userMapper;
@Autowired
private QuartzService quartzService;
@SneakyThrows
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
log.warn("start SomThingTimeJob !! ");
//写自己要实现的业务逻辑
Integer userId = (Integer) context.getJobDetail().getJobDataMap().get("userId");
//可以使用getJobDetail的getJobDataMap方法获取传入的其他参数辅助自己的业务实现
User users = userMapper.selectUserById(userId);
System.out.println(new Date()+"用户姓名"+users.getUserName());
log.warn("finish SomThingTimeJob !! ");
}
}
package com.example.quartz3.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author 一个达不刘
* cron表达式生成工具类
*
*/
public class CronUtil {
/**
* 生成指定格式日期字符
*
* @param date 日期
* @param dateFormat : e.g:yyyy-MM-dd HH:mm:ss
* @return formatTimeStr
*/
public static String formatDateByPattern(Date date, String dateFormat) {
dateFormat = dateFormat == null ? "yyyy-MM-dd HH:mm:ss" : dateFormat;
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
return date != null ? sdf.format(date) : null;
}
/**
* 生成cron表达式 ss mm HH dd MM ? yyyy
* convert Date to cron ,eg. "0 06 10 15 1 ? 2014"
*
* @param date : 时间点
*/
public static String getCron(Date date) {
String dateFormat = "ss mm HH dd MM ? yyyy";
return formatDateByPattern(date, dateFormat);
}
/**
* 生成cron表达式 ss mm HH dd MM ?
* convert Date to cron ,eg. "0 06 10 15 1 ?"
*
* @param date : 时间点
* @param type : 类型 日/周/月
*/
public static String getLoopCron(Date date, String type, Integer week, Integer day) {
String dateFormat = "ss mm HH";
// dd MM ?
String cron = formatDateByPattern(date, dateFormat);
switch (type) {
case "Day":
return cron + " * * ?";
case "Week":
return cron + " ? * " + getCurrentWeek(week);
case "Month":
return cron + " " + day + " * ?";
default:
return "false";
}
}
/**
* 获取当前星期的字符 MON TUE WED THU FRI SAT SUN
*
* @param week : 周 1 2 3 4 5 6 7
* @return 星期字符
*/
public static String getCurrentWeek(Integer week) {
String[] weeks = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
return weeks[week - 1];
}
public static void main(String[] args) {
Date date = new Date();
//String dateFormat = "ss mm HH dd MM ? yyyy";
//String cron = formatDateByPattern(date, dateFormat);
//System.out.println("原始:" + cron);
//
//String day = formatDateByPattern(date, "ss mm HH");
//System.out.println("日报:" + day + " * * ?");
//
0 15 10 ? * MON 每周一上午10点15分
动参为 周
//String week = formatDateByPattern(date, "ss mm HH");
//System.out.println("周报:" + week + " ? * MON");
//
0 15 9 10 * ? 每月10号9点15分
动参为 号
//String month = formatDateByPattern(date, "ss mm HH");
//System.out.println("月报:" + month + " 10 * ?");
}
}
package com.example.quartz3.utils;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* @author 一个达不刘
* @date 2023/3/20 18:34
*/
public class ClassUtil {
@SuppressWarnings("unchecked")
public static Class extends QuartzJobBean> getClass(String classname) throws Exception {
Class> class1 = Class.forName(classname);
return (Class extends QuartzJobBean>) class1;
}
}
为什么使用这个转换器的原因是创建job的时候
public void addJob(Class extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,int jobTimes)
jobClass是一个.class的对象,但是传入的参数不可能是一个.class的对象,所以需要一个转换器
package com.example.quartz3.controller;
import com.example.quartz3.job.QuartzService;
import com.example.quartz3.utils.ClassUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author 钟于一个达不刘
*/
@RestController
@RequestMapping(value = "/job")
public class JobController {
@Autowired
private QuartzService quartzService;
/**
* @param jobClassName
* @param jobGroupName
* @param cronExpression
* @throws Exception
*/
@PostMapping(value = "/addjob")
public void addjob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName,
@RequestParam(value = "cronExpression") String cronExpression,
@RequestParam("userId") Integer userId) throws Exception {
quartzService.addJob(ClassUtil.getClass(jobClassName), jobClassName, jobGroupName, cronExpression,userId);
}
/**
* @param jobClassName
* @param jobGroupName
* @throws Exception
*/
@PostMapping(value = "/pausejob")
public void pausejob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
quartzService.pauseJob(jobClassName, jobGroupName);
}
/**
* @param jobClassName
* @param jobGroupName
* @throws Exception
*/
@PostMapping(value = "/resumejob")
public void resumejob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
quartzService.resumeJob(jobClassName, jobGroupName);
}
/**
* @param jobClassName
* @param jobGroupName
* @throws Exception
*/
@PostMapping(value = "/deletejob")
public void deletejob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
quartzService.deleteJob(jobClassName, jobGroupName);
}
}
package com.example.quartz3.mapper;
import com.example.quartz3.domain.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author 一个达不刘
* @date 2023/3/19 19:28
*/
@Mapper
public interface UserMapper {
List selectList(Object o);
int insertUser(User user);
User selectUserById(int id);
}
package com.example.quartz3.mapper;
import com.example.quartz3.domain.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @author 一个达不刘
* @date 2023/3/19 19:28
*/
@Mapper
public interface UserMapper {
List selectList(Object o);
int insertUser(User user);
User selectUserById(int id);
}
有志向于IT技术的小伙伴,或者想要一些IT技术的资料,可以来QQ群获取:526519295