无需配置,直接写死的使用
import org.springframework.scheduling.annotation.Scheduled;
@Slf4j
@Component
public class Test {
@Autowired
private StudentService studentService;
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void execute(){
List<Student> students = studentService.findAll();
log.info("cron run"+students);
}
}
三大核心类 Scheduler(调度器),Trigger(触发器),JObDetail(作业类)。Trigger指定JObDetail什么时候发布任务。
1.Quartz 简介
Quartz 是 OpenSymphony 开源组织在 Job Scheduling 领域又一个开源项目,是完全由 Java 开发的一个开源任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。 Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中,它提供了巨大的灵活性而不牺牲简单性
当定时任务愈加复杂时,使用 Spring 注解 @Schedule 已经不能满足业务需要
在项目开发中,经常需要定时任务来帮助我们来做一些内容,如定时派息、跑批对账、将任务纳入日程或者从日程中取消,开始,停止,暂停日程进度等。SpringBoot 中现在有两种方案可以选择,第一种是 SpringBoot 内置的方式简单注解就可以使用,当然如果需要更复杂的应用场景还是得 Quartz 上场,Quartz 目前是 Java 体系中最完善的定时方案
2.Quartz 优点
3.核心概念
Scheduler:Quartz 中的任务调度器,通过 Trigger 和 JobDetail
可以用来调度、暂停和删除任务。调度器就相当于一个容器,装载着任务和触发器,该类是一个接口,代表一个 Quartz的独立运行容器,Trigger 和 JobDetail 可以注册到 Scheduler 中,两者在 Scheduler中拥有各自的组及名称,组及名称是 Scheduler 查找定位容器中某一对象的依据,Trigger 的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和 Trigger 的组和名称相同,因为它们是不同类型的)
Trigger:Quartz中的触发器,是一个类,描述触发 Job 执行的时间触发规则,主要有 SimpleTrigger 和
CronTrigger 这两个子类。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger 是最适合的选择;而
CronTrigger 则可以通过 Cron 表达式定义出各种复杂时间规则的调度方案:如工作日周一到周五的 15:00 ~
16:00 执行调度等
JobDetail:Quartz 中需要执行的任务详情,包括了任务的唯一标识和具体要执行的任务,可以通过 JobDataMap
往任务中传递数据 Job:Quartz 中具体的任务,包含了执行任务的具体方法。是一个接口,只定义一个方法 execute()
方法,在实现接口的 execute() 方法中编写所需要定时执行的 Job
4.简易理解
5.Cron 表达式
Cron 表达式是一个字符串,包括 6~7 个时间元素,在 Quartz 中可以用于指定任务的执行时间
6.Cron 语法
Seconds Minutes Hours DayofMonth Month DayofWeek
秒 分钟 小时 日期天/日 日期月份 星期
7.在线 Cron 表达式生成器
其实 Cron 表达式无需多记,需要使用的时候直接使用在线生成器就可以了,地址:https://cron.qqe2.com/
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
或者
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
或者 (如果启动项目后,不加载QZ的话,用下面的依赖)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>
3.yml配置文件
server.port=8087
# mysql 数据库连接
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://192.158.58.100:3306/springboot?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&autoReconnect=true
spring.datasource.username =hadoop
spring.datasource.password =root
spring.datasource.hikari.max-lifetime=120000
#druid 连接池配置
spring.datasource.druid.initial-size=3
spring.datasource.druid.min-idle=3
spring.datasource.druid.max-active=10
spring.datasource.druid.max-wait=60000
hibernate.node.name=node5
#整合mybatis
#给pojo实体类起别名
#mybatis.type-aliases-package=com.kuang.pojo
#接口的配置文件的位置 我这里接口配置文件是UserMapper.xml 如下图所示
mybatis.mapper-locations=classpath:mapper/*.xml
#打印sql语句-打印接口mapper中的
logging.level.com.tject.mapper=debug
#开启驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true
#打印mapper.xml配置文件中的sql语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#
#如果数据库中没有这个表 则根据entity直接创建
#################
###Spring jpa
##################
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto = update
##自动建表通过以下策略来映射
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
4.新建任务表实体类SchedulerJobInfo
/**
*@descriprion: 定时任务-实体类
*@author: xujirong
*@date: 2022/8/29 21:43
*/
@Data
public class SchedulerJobInfo {
private String id;
private String version="1.0";
private Date createTime=new Date();
/**任务英文名称*/
private String jobName;
/**任务中文名称*/
private String chineseName;
private String jobBean;
/**定时任务所属组*/
private String jobGroup;
/**cron表达式*/
private String cron;
private String status;
private String remark;
private String node;
private String override;
private String type;
private String executorName;
private String executorParam;
private String mchId;
private String mchPassword;
private String v3Password;
private String appId;
private String mchApiSerial;
private String shellString;
private String sqlCode;
private String sqlParam;
private String isDownloadHdfs;
private String isDownloadDb;
private String periods;
}
5.新建接口注解CronJob
/**
* @belongProject:定时任务-接口注解类
* @belongPackage:com.tjetc.annotation
* @author:xujirong
* @dscription:TODO
* @date:2022-09-02 22:16
* @version:1.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CronJob {
/**任务英文名称*/
String beanName() default "";
/**任务中文名称*/
String chineseName() default "";
/**cron表达式*/
String cron() default "";
/**定时任务所属组*/
String group() default "";
/**定时任务节点*/
String node() default "node5";
}
6.新建InitRunner(初始化定时任务)
/**
* @belongProject:项目启动时-加载定时任务
* @belongPackage:com.tjetc.scheduler
* @author:xujirong
* @dscription: Trigger:触发器,Job:任务,Scheduler:调度器
* @date:2022-09-02 22:38
* @version:1.0
*/
@Component
@Order(value = 1) //执行顺序控制
public class InitRunner implements ApplicationRunner {
Logger logger = LoggerFactory.getLogger(InitRunner.class);
/**
* ApplicationContext是Spring中的核心接口和容器,
* 允许容器通过应用程序上下文环境创建、获取、管理bean。
* 在构建容器的时候,创建对象采用的策略是立即加载的方式,
* 即只要一读取完配置文件就立即创建配置文件中配置的对象
*/
@Autowired
private ApplicationContext applicationContext;
/**增删改查调度表(业务系统)-在系统表中*/
@Autowired
private SchedulerJobService schedulerJobService;
/**增删改查调度任务(框架系统)-Quartz框架中定义任务*/
@Autowired
private IQuartzServiceImpl iQuartzService;
/**根据节点名称查询调度表中的任务*/
@Value("${hibernate.node.name}")
private String nodeName;
/**
*@descriprion: 项目启动run方法-初始化cron定时任务
*@author: xujirong
*@date: 2022/9/3 13:01
*@return: void
*/
@Override
public void run(ApplicationArguments args) throws Exception {
//ApplicationArguments:应用程序启动参数
//若SpringUtils中的ApplicationContext为空,则通过注解注入bean的方式重新赋值
if (SpringUtils.getApplicationContext()==null){
SpringUtils.setApplicationContext(applicationContext);
}
loadSchedulerCron();
List<Map<String, Object>> mapNodeList = schedulerJobService.selectSchedulerByNode(nodeName);
System.out.println("mapList.size() = " + mapNodeList.size());
arrowFunction(mapNodeList);
//遍历所有系统定义的任务,添加到加到Quartz框架中
for (Map<String, Object> map : mapNodeList) {
logger.info("添加的定时任务->job_name="+map.get("job_name")+",job_group="+map.get("job_group")+",cron="+map.get("cron")+",job_bean="+map.get("job_bean"));
iQuartzService.addJob((String)map.get("job_name"),
(String)map.get("job_group"),
(String)map.get("cron"),
(String)map.get("job_bean"),"job_param_"+ UUID.randomUUID().toString().substring(0,6));
}
}
/**
*@descriprion: 加载项目中自定义的-定时任务
*@author: xujirong
*@date: 2022/9/3 20:25
*@return: void
*/
public void loadSchedulerCron(){
//获取被@Cron注解定义的任务-集合
Map<String, Object> objectMap = SpringUtils.getApplicationContext().getBeansWithAnnotation(CronJob.class);
for (Object k:objectMap.keySet()){
Object o = objectMap.get(k);
//校验被注解@Cron的类是否为任务调度类(继承QuartzJobBean)
if (o instanceof QuartzJobBean){
//获取定时任务对象
CronJob annotation = AopUtils.getTargetClass(o).getAnnotation(CronJob.class);
//校验cron表达式的有效性
if(CronExpression.isValidExpression(annotation.cron())){
String beanName = annotation.beanName();
//判断任务是否已存在
Map<String,Object> map = schedulerJobService.queryByBeanName(beanName);
if (map==null || map.size()==0){
SchedulerJobInfo schedulerJobInfo = new SchedulerJobInfo();
schedulerJobInfo.setChineseName(annotation.chineseName());
schedulerJobInfo.setJobBean(annotation.beanName());
schedulerJobInfo.setJobGroup(annotation.group());
schedulerJobInfo.setCron(annotation.cron());
schedulerJobInfo.setNode(annotation.node());
//保存新增任务
//schedulerJobService.addJob(schedulerJobInfo);
}
}else {
logger.info("表达式->"+annotation.cron()+"有误");
}
}
}
}
/**
*@descriprion: 箭头函数(arrowFunction)的使用
*@author: xujirong
*@date: 2022/9/3 23:05
*@return:
*/
public void arrowFunction(List<Map<String, Object>> list){
//以下则-得到一个,以job_name为key的Map为value的Map对象
Map<String, Map<String, Object>> oldMaps =
list.stream().filter(item ->{
if("test".equals(item.get("job_group"))){
return true; //留下
}
return false;
}).collect(Collectors.toMap(obj -> ((Map) obj).get("job_name").toString(), obj -> obj));
System.out.println("oldMaps = " + oldMaps);
}
}
7.新建SpringUtils-获取上下文对象-进而获取想要的bean
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.utils
* @author:xujirong
* @dscription:TODO
* @date:2022-08-28 20:10
* @version:1.0
*/
public class SpringUtils {
/**
* ApplicationContext是Spring中的核心接口和容器,
* 允许容器通过应用程序上下文环境创建、获取、管理bean。
* 在构建容器的时候,创建对象采用的策略是立即加载的方式,
* 即只要一读取完配置文件就立即创建配置文件中配置的对象
*/
private static ApplicationContext applicationContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
}
8.新建SchedulerJobService接口
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.service
* @author:xujirong
* @dscription:任务调度-任务接口
* @date:2022-08-29 21:44
* @version:1.0
*/
public interface SchedulerJobService {
/**
*@descriprion: 查询所有定时任务
*@author: xujirong
*@date: 2022/8/29 21:45
*@return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
*/
List<Map<String,Object>> selectSchedulerJobAll();
/**
*@descriprion: 根据node节点查询任务
*@author: xujirong
*@date: 2022/9/3 14:37
*@return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
*/
List<Map<String, Object>> selectSchedulerByNode(String nodeName);
/**
*@descriprion: 根据任务beanName名称查询任务
*@author: xujirong
*@date: 2022/9/3 14:37
*@return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
*/
Map<String, Object> queryByBeanName(String beanName);
}
9.新建SchedulerJobService 接口的实现类
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.service.impl
* @author:xujirong
* @dscription:TODO
* @date:2022-08-29 21:44
* @version:1.0
*/
@Scope("prototype")
@Service
public class SchedulerJobServiceImpl implements SchedulerJobService {
@Autowired
private SchedulerJobMapper schedulerJobMapper;
@Override
public List<Map<String, Object>> selectSchedulerJobAll() {
return schedulerJobMapper.selectSchedulerJobAll();
}
@Override
public List<Map<String, Object>> selectSchedulerByNode(String nodeName) {
return schedulerJobMapper.selectSchedulerByNode(nodeName);
}
@Override
public Map<String, Object> queryByBeanName(String beanName) {
return schedulerJobMapper.queryByBeanName(beanName);
}
}
10.新建schedulerJobMapper接口-实现和数据库表的数据交互
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.mapper
* @author:xujirong
* @dscription:TODO
* @date:2022-08-29 21:46
* @version:1.0
*/
@Repository
public interface SchedulerJobMapper {
List<Map<String, Object>> selectSchedulerJobAll();
List<Map<String, Object>> selectSchedulerByNode(String nodeName);
Map<String, Object> queryByBeanName(String beanName);
}
11.新建SchedulerJobMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tjetc.mapper.SchedulerJobMapper">
<select id="selectSchedulerJobAll" resultType="java.util.Map">
select * from t_scheduler_job
</select>
<select id="selectSchedulerByNode" parameterType="string" resultType="java.util.Map">
select * from t_scheduler_job where node=#{nodeName}
</select>
<select id="queryByBeanName" parameterType="string" resultType="java.util.Map">
select * from t_scheduler_job where job_bean=#{beanName}
</select>
</mapper>
12.新建IQuartzService任务调度接口(重点)
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.service
* @author:xujirong
* @dscription:调度任务接口
* @date:2022-09-03 13:22
* @version:1.0
*/
public interface IQuartzService {
/**
* 添加一个任务
*
* @param jobName job的名称
* @param jobGroupName job的组名称
* @param jobTime 时间表达式 (这是每隔多少秒为一次任务)
* @param runCount 运行的次数 (<0:表示不限次数)
*/
public void addJob(String jobName, String jobGroupName, int jobTime,
int runCount,String beanName,Object jobParam) throws Exception;
/**
* 增加一个job
*
* @param jobName 任务名称
* @param jobGroupName 任务组名
* @param jobTime 时间表达式 (如:0/5 * * * * ? )
*/
public void addJob(String jobName, String jobGroupName, String jobTime,String beanName,Object jobParam) throws Exception;
/**
* 修改一个job任务
*
* @param jobName 名称
* @param jobGroupName 组名
* @param jobTime job的Corn时间
*/
public void updateJob(String jobName, String beanName, String jobGroupName, String jobTime, Object jobParam) throws Exception;
/**
* 删除一个Job任务
*
* @param jobName 名称
* @param jobGroupName 组名称
*/
public void deleteJob(String jobName, String jobGroupName) throws Exception;
/**
* 暂停一个Job任务
*
* @param jobName 名称
* @param jobGroupName 组名
*/
public void pauseJob(String jobName, String jobGroupName) throws Exception;
/**
* 恢复一个任务
*
* @param jobName 名称
* @param jobGroupName 组名
*/
public void resumeJob(String jobName, String jobGroupName) throws Exception;
/**
* 立即执行一个任务
*
* @param jobName 名称
* @param jobGroupName 组名
*/
public void runAJobNow(String jobName, String jobGroupName) throws Exception;
/**
* 获取正在运行的JOB
* @return
* @throws Exception
*/
public List<Map<String,Object>> getRunningJobList() throws Exception;
/**
* 获取所有的JOB
* @return
* @throws Exception
*/
public List<Map<String,Object>> getAllJobList() throws Exception;
}
13.新建IQuartzService任务调度接口实现类IQuartzServiceImpl(重点)
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.hibernate02.service.impl
* @author:xujirong
* @dscription:调度任务实现类
* @date:2022-08-28 14:18
* @version:1.0
*/
@Slf4j
@Service
public class IQuartzServiceImpl implements IQuartzService {
private Logger logger = LoggerFactory.getLogger(IQuartzServiceImpl.class);
@Autowired
private Scheduler scheduler;
@Override
public void addJob(String jobName, String jobGroupName, int jobTime, int runCount,String beanName,Object jobParam) throws Exception {
logger.info(" 新增一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + ",jobTime=" + jobTime + "," +
"runCount=" + runCount);
QuartzJobBean bean = SpringUtils.getApplicationContext().getBean(beanName,QuartzJobBean.class);
Date date = JobUtils.addJob(scheduler, bean.getClass(), jobName, jobGroupName, jobTime, runCount,jobParam);
logger.info(" job任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + " 执行完成 . " + date);
}
@Override
public void addJob(String jobName, String jobGroupName, String cron,String beanName,Object jobParam) throws Exception {
logger.info(" 新增一个任务 jobName=" + jobName + ",jobGroupName" + ",jobGroupName="+jobGroupName + ",jobTime=" + cron);
QuartzJobBean bean = SpringUtils.getApplicationContext().getBean(beanName,QuartzJobBean.class);
Date date = JobUtils.addJob(scheduler, bean.getClass(), jobName, jobGroupName, cron,jobParam);
logger.info(" job任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + " 执行完成 . " + date);
}
/**
* 修改 一个job的 时间表达式
*
* @param jobName
* @param jobGroupName
* @param jobTime
*/
@Override
public void updateJob(String jobName, String beanName, String jobGroupName,String jobTime, Object jobParam) throws Exception {
logger.info(" 修改一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + ",jobTime=" + jobTime);
QuartzJobBean bean = SpringUtils.getApplicationContext().getBean(beanName,QuartzJobBean.class);
JobUtils.updateJob(scheduler, bean.getClass() ,jobName, jobGroupName, jobTime,jobParam);
logger.info(" job任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + " 执行完成 . ");
}
/**
* 删除任务一个job
*
* @param jobName 任务名称
* @param jobGroupName 任务组名
*/
@Override
public void deleteJob(String jobName, String jobGroupName) throws Exception {
logger.info(" 删除一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + ",jobTime=");
boolean result = JobUtils.deleteJob(scheduler, jobName, jobGroupName);
logger.info(" job任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + " 执行完成." + result);
}
/**
* 暂停一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void pauseJob(String jobName, String jobGroupName) throws Exception {
logger.info(" 暂停一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + ",jobTime=");
JobUtils.pauseJob(scheduler, jobName, jobGroupName);
logger.info(" job任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + " 执行完成.");
}
/**
* 恢复一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void resumeJob(String jobName, String jobGroupName) throws Exception {
logger.info(" 恢复一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + ",jobTime=");
JobUtils.resumeJob(scheduler, jobName, jobGroupName);
logger.info(" 恢复一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + "执行完成");
}
/**
* 立即执行一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void runAJobNow(String jobName, String jobGroupName) throws Exception {
logger.info(" 立即执行一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + ",jobTime=");
JobUtils.runAJobNow(scheduler, jobName, jobGroupName);
logger.info(" 立即执行一个任务 jobName=" + jobName + ",jobGroupName" + jobGroupName + "完成 ...");
}
@Override
public List<Map<String,Object>> getRunningJobList() throws Exception {
return JobUtils.queryRunJob(scheduler);
}
@Override
public List<Map<String,Object>> getAllJobList() throws Exception {
return JobUtils.queryAllJob(scheduler);
}
}
14.新建JobUtils 任务调度工具类
package com.tjetc.utils;
import com.mchange.v1.util.MapUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.*;
/**
*@descriprion: 调度任务工具类
*@author: xujirong
*@date: 2022/9/4 11:32
*/
public class JobUtils {
/**
* 增加一个job
*
* @param jobClass 任务实现类
* @param jobName 任务名称
* @param jobGroupName 任务组名
* @param jobTime 时间表达式 (这是每隔多少秒为一次任务)
* @param jobTimes 运行的次数 (<0:表示不限次数)
*/
public static Date addJob(Scheduler scheduler, Class<? extends QuartzJobBean> jobClass, String jobName, String
jobGroupName, int jobTime,
int jobTimes, Object jobParam) throws Exception {
Trigger trigger = null;
JobDataMap jobDataMap =new JobDataMap();
if(jobParam != null){
jobDataMap.put("job_param",jobParam);
}
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).setJobData(jobDataMap)
.build();
// 使用simpleTrigger规则
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();
}
return scheduler.scheduleJob(jobDetail, trigger);
}
/**
* 增加一个job
* Trigger:触发器,Job:任务,Scheduler:调度器
* @param jobClass 任务实现类
* @param jobName 任务名称
* @param jobGroupName 任务组名
* @param cron 时间表达式 (如:0/5 * * * * ? )
*/
public static Date addJob(Scheduler scheduler, Class<? extends QuartzJobBean> jobClass, String jobName, String
jobGroupName, String cron, Object jobParam) throws Exception {
// 创建jobDetail实例,绑定Job实现类
// 指明job的名称,所在组的名称,以及绑定job类
// 任务名称和组构成任务key
JobDataMap jobDataMap =new JobDataMap();
if(jobParam != null){
jobDataMap.put("job_param",jobParam);
}
// JobBuilder.newJob(jobClass)构建任务-指向绑定任务的类
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).setJobData(jobDataMap).build();
// 定义调度触发规则
// 使用cornTrigger规则
// 触发器key
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(cron)).startNow().build();
// 把作业和触发器注册到任务调度中
return scheduler.scheduleJob(jobDetail, trigger);
}
/**
* 修改 一个job的 时间表达式
*
* @param jobName
* @param jobGroupName
* @param jobTime
*/
public static Date updateJob(Scheduler scheduler, Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Object jobParam) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
JobDataMap jobDataMap =new JobDataMap();
if(jobParam != null){
jobDataMap.put("job_param",jobParam);
}
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).setJobData(jobDataMap)
.build();
deleteJob( scheduler, jobName, jobGroupName); //首先删除旧作业
scheduler.scheduleJob(jobDetail, trigger); //注册新作业到任务调度中
return scheduler.rescheduleJob(triggerKey, trigger); //重启触发器,更新触发参数
}
/**
* 删除任务一个job
*
* @param jobName 任务名称
* @param jobGroupName 任务组名
*/
public static boolean deleteJob(Scheduler scheduler, String jobName, String jobGroupName) throws SchedulerException {
return scheduler.deleteJob(new JobKey(jobName, jobGroupName));
}
/**
* 暂停一个job
*
* @param jobName
* @param jobGroupName
*/
public static void pauseJob(Scheduler scheduler, String jobName, String jobGroupName) throws Exception {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.pauseJob(jobKey);
}
/**
* 恢复一个job
*
* @param jobName
* @param jobGroupName
*/
public static void resumeJob(Scheduler scheduler, String jobName, String jobGroupName) throws Exception {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.resumeJob(jobKey);
}
/**
* 立即执行一个job
*
* @param jobName
* @param jobGroupName
*/
public static void runAJobNow(Scheduler scheduler, String jobName, String jobGroupName) throws Exception {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.triggerJob(jobKey);
}
/**
* 获取所有计划中的任务列表
*
* @return
*/
public static List<Map<String, Object>> queryAllJob(Scheduler scheduler) {
List<Map<String, Object>> jobList = null;
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
jobList = new ArrayList<Map<String, Object>>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
JobDataMap jobDataMap = scheduler.getJobDetail(jobKey).getJobDataMap();
for (Trigger trigger : triggers) {
Map<String, Object> map = new HashMap<>();
map.put("jobName", jobKey.getName());
map.put("jobGroupName", jobKey.getGroup());
map.put("description", "触发器:" + trigger.getKey());
//Object jobParam = MapUtils.getObject(jobDataMap,"job_param");
//map.put("job_param",jobParam);
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
map.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put("jobTime", cronExpression);
}
jobList.add(map);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}
/**
* 获取所有正在运行的job
*
* @return
*/
public static List<Map<String, Object>> queryRunJob(Scheduler scheduler) {
List<Map<String, Object>> jobList = null;
try {
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
Map<String, Object> map = new HashMap<String, Object>();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
map.put("jobName", jobKey.getName());
map.put("jobGroupName", jobKey.getGroup());
map.put("description", "触发器:" + trigger.getKey());
JobDataMap jobDataMap = trigger.getJobDataMap();
//Object jobParam = MapUtils.getObject(jobDataMap,"job_param");
//map.put("job_param",jobParam);
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
map.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put("jobTime", cronExpression);
}
jobList.add(map);
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}
}
15.新建SchedulerJobBean->定时任务定义
/**
* @belongProject:hibernate
* @belongPackage:com.tjetc.scheduler.test
* @author:xujirong
* @dscription:定时任务表-调度测试
* @date:2022-09-03 15:13
* @version:1.0
*/
@Component(value = "SchedulerJobBean")//给bean取一个名字
@CronJob(cron = "0/5 * * * * ? *",beanName = "SchedulerJobBean",chineseName = "定时任务测试",group = "test",node = "node5")
public class SchedulerJobBean extends QuartzJobBean {
@Autowired
private SchedulerJobMapper schedulerJobMapper;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
List<Map<String, Object>> mapList = schedulerJobMapper.selectSchedulerJobAll();
System.out.println("mapList = " + mapList);
}
}
16.在springboot启动类中的相关注解
@SpringBootApplication
@EnableScheduling
@MapperScan("com.tjetc.mapper.**")
@ComponentScan("com.tjetc.scheduler.**")
@ComponentScan("com.tjetc.service.*")
public class SpringbootQuartzApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootQuartzApplication.class, args);
}
}