1.pom 依赖配置和生成数据库表
1.1 pom 依赖配置
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.16</version> </dependency>
1.2 生成quartz相关的数据库表
在数据库中添加quartz相关表
共11张表,前6张都是关于各种triggers的信息,后面包括job,悲观锁,调度状态等信息;相关表操作在类StdJDBCDelegate中,相关sql语句在StdJDBCConstants中;
(1) qrtz_blob_triggers
自定义的triggers使用blob类型进行存储,非自定义的triggers不会存放在此表中,Quartz提供的triggers包括:CronTrigger,CalendarIntervalTrigger,
DailyTimeIntervalTrigger以及SimpleTrigger,这几个trigger信息会保存在后面的几张表中;
(2)qrtz_cron_triggers
存储CronTrigger,这也是我们使用最多的触发器,在配置文件中做如下配置,即可在qrtz_cron_triggers生成记录:
(3)qrtz_simple_triggers
存储SimpleTrigger,在配置文件中做如下配置,即可在qrtz_simple_triggers生成记录:
(4)qrtz_simprop_triggers
存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种类型的触发器,使用CalendarIntervalTrigger做如下配置:
CalendarIntervalTrigger没有对应的FactoryBean,直接设置实现类CalendarIntervalTriggerImpl;指定的重复周期是1,默认单位是天,也就是每天执行一次,查看表如下:提供了3个string类型的参数,2个int类型的参数,2个long类型的参数,2个decimal类型的参数以及2个boolean类型的参数;具体每个参数是什么含义,根据不同的trigger类型存放各自的参数;
(5)qrtz_fired_triggers
存储已经触发的trigger相关信息,trigger随着时间的推移状态发生变化,直到最后trigger执行完成,从表中被删除;已SimpleTrigger为例重复3次执行,查询表:
(6)qrtz_triggers
触发器的基本信息
(7)qrtz_job_details
存储jobDetails信息,相关信息在定义的时候指定,如上面定义的JobDetailFactoryBean,查询数据库:
JOB_DATA存放的就是定义task时指定的jobDataMap属性,所以此属性需要实现Serializable接口,方便持久化到数据库;
(8)qrtz_calendars
Quartz为我们提供了日历的功能,可以自己定义一个时间段,可以控制触发器在这个时间段内触发或者不触发;现在提供6种类型:AnnualCalendar,CronCalendar,DailyCalendar,HolidayCalendar,MonthlyCalendar,WeeklyCalendar;
(9)qrtz_paused_trigger_grps
存放暂停掉的触发器,测试手动暂停firstCronTrigger
(10)qrtz_scheduler_state
存储所有节点的scheduler,会定期检查scheduler是否失效,启动多个scheduler,查询数据库:
记录了最后最新的检查时间,在quartz.properties中设置了CHECKIN_INTERVAL为1000,也就是每秒检查一次;
(11)qrtz_locks
Quartz提供的锁表,为多个节点调度提供分布式锁,实现分布式调度,默认有2个锁:
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
# I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
commit;
2.注册Quartz 任务(Job) 工厂和注册调度工厂
2.1 注册Quartz 任务(Job) 工厂
package com.ttbank.flep.config; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.AdaptableJobFactory; import org.springframework.stereotype.Component; /** * @Author lucky * @Date 2022/4/1 15:50 * 注册Quartz 任务(Job) 工厂 */ @Component public class QuartzJobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; //AutowireCapableBeanFactory提供了自动装配Bean的实现,提供bean创建(带有构造函数解析)、属性填充、连接(包括自动装配)和初始化 @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //调用父类的方法 Object jobInstance = super.createJobInstance(bundle); //进行注入 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
2.2 配置数据库连接池
(1)读取yaml文件中的配置项
package com.ttbank.flep.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @Author lucky * @Date 2022/3/31 10:22 */ @Data @Component @ConfigurationProperties(prefix = "spring.datasource.druid") public class DataSourceProperties { private String driverClassName; private String url; private String username; private String password; private int initialSize; private int minIdle; private int maxActive=100; private long maxWait; private long timeBetweenEvictionRunsMillis; private long minEvictableIdleTimeMillis; private String validationQuery; private boolean testWhileIdle; private boolean testOnBorrow; private boolean testOnReturn; }
(2)配置数据库连接池,注入DataSource
package com.ttbank.flep.config; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.sql.SQLException; /** * @Author lucky * @Date 2022/4/1 9:18 * 配置数据库连接池,注入DataSource */ @Configuration public class DruidConfig { @Autowired private DataSourceProperties dataSourceProperties; @Bean public DataSource druidDataSource(){ DruidDataSource druidDataSource=new DruidDataSource(); druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName()); druidDataSource.setUrl(dataSourceProperties.getUrl()); druidDataSource.setUsername(dataSourceProperties.getUsername()); druidDataSource.setPassword(dataSourceProperties.getPassword()); druidDataSource.setInitialSize(dataSourceProperties.getInitialSize()); druidDataSource.setMinIdle(dataSourceProperties.getMinIdle()); druidDataSource.setMaxActive(dataSourceProperties.getMaxActive()); druidDataSource.setMaxWait(dataSourceProperties.getMaxWait()); druidDataSource.setTimeBetweenEvictionRunsMillis(dataSourceProperties.getTimeBetweenEvictionRunsMillis()); druidDataSource.setMinEvictableIdleTimeMillis(dataSourceProperties.getMinEvictableIdleTimeMillis()); druidDataSource.setValidationQuery(dataSourceProperties.getValidationQuery()); druidDataSource.setTestWhileIdle(dataSourceProperties.isTestWhileIdle()); druidDataSource.setTestOnBorrow(dataSourceProperties.isTestOnBorrow()); druidDataSource.setTestOnReturn(dataSourceProperties.isTestOnReturn()); try { druidDataSource.init(); } catch (SQLException e) { e.printStackTrace(); } return druidDataSource; } }
2.3 注册调度工厂
package com.ttbank.flep.config; import org.quartz.Scheduler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.quartz.LocalDataSourceJobStore; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import javax.sql.DataSource; import java.io.IOException; /** * @Author lucky * @Date 2022/4/1 16:23 * 注册调度工厂 */ @Configuration public class QuartzConfig { @Autowired private QuartzJobFactory jobFactory; @Autowired private DataSource dataSource; @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException{ //01 获取配置属性 PropertiesFactoryBean propertiesFactoryBean=new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); //在quartz.properties中的属性被读取并注入后再初始化对象; propertiesFactoryBean.afterPropertiesSet(); //02 创建SchedulerFactoryBean SchedulerFactoryBean factory=new SchedulerFactoryBean(); factory.setQuartzProperties(propertiesFactoryBean.getObject()); factory.setJobFactory(jobFactory); factory.setApplicationContextSchedulerContextKey("applicationContextKey"); //当spring关闭时,会等待所有已经启动的quartz job结束后才能完全shutdown factory.setWaitForJobsToCompleteOnShutdown(true); //是否覆盖已经存在的JOB factory.setOverwriteExistingJobs(false); factory.setStartupDelay(10); factory.setDataSource(dataSource); return factory; } @Bean(name="scheduler") public Scheduler scheduler() throws IOException{ Scheduler scheduler = schedulerFactoryBean().getScheduler(); return scheduler; } }
3.controller
package com.ttbank.flep.controller; import com.ttbank.flep.service.QuartzService; import dto.AppQuartzDTO; import dto.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @Author lucky * @Date 2022/4/1 17:50 */ @RestController @RequestMapping("/quartztest") public class QuartzController { @Autowired QuartzService quartzService; /** * 添加任务 */ @PostMapping("/addJob") public Result addJob(@RequestBody AppQuartzDTO appQuartzDTO){ quartzService.addJob(appQuartzDTO); return Result.success(); } /** * 暂停任务 */ @PostMapping("/pauseJob") public Result pauseJob(@RequestParam String jobName,@RequestParam String jobGroupName){ quartzService.pauseJob(jobName,jobGroupName); return Result.success(); } /** * 恢复任务 */ @PostMapping("/resumeJob") public Result resumeJob(@RequestParam String jobName,@RequestParam String jobGroupName){ quartzService.resumeJob(jobName,jobGroupName); return Result.success(); } /** * 添加任务 */ @PostMapping("/modifyJob") public void modifyJob(@RequestBody AppQuartzDTO appQuartzDTO){ quartzService.modifyJob(appQuartzDTO); } }
4.Service
(1)QuartzService接口
package com.ttbank.flep.service; import dto.AppQuartzDTO; /** * @Author lucky * @Date 2022/4/2 11:49 */ public interface QuartzService { /** * 新建任务 * @param appQuartzDTO */ void addJob(AppQuartzDTO appQuartzDTO); /** * 暂停任务 * @param jobName * @param jobGroupName */ void pauseJob(String jobName,String jobGroupName); /** * 恢复任务 * @param jobName * @param jobGroupName */ void resumeJob(String jobName, String jobGroupName); /** * 修改任务 * @param appQuartzDTO */ void modifyJob(AppQuartzDTO appQuartzDTO); }
(2) QuartzServiceImpl
package com.ttbank.flep.service.impl; import com.ttbank.flep.constant.QuartzJobDataKey; import com.ttbank.flep.job.BaseJob; import com.ttbank.flep.service.QuartzService; import dto.AppQuartzDTO; import lombok.extern.slf4j.Slf4j; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; /** * @Author lucky * @Date 2022/4/2 15:34 */ @Slf4j @Service public class QuartzServiceImpl implements QuartzService { @Autowired @Qualifier("scheduler") private Scheduler scheduler; @PostConstruct public void startScheduler(){ try { scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } @Override public void addJob(AppQuartzDTO appQuartzDTO) { try { //01 构建job信息; JobDetail jobDetail = JobBuilder.newJob(getClass(appQuartzDTO.getClassName().trim()).getClass()) .withIdentity(appQuartzDTO.getJobName(), appQuartzDTO.getJobGroup()) .build(); //02 表达式调度构建器(任务执行的时间) CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartzDTO.getCronExpression()); //03 按新的CronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(appQuartzDTO.getJobName(), appQuartzDTO.getJobGroup()) .withSchedule(cronScheduleBuilder) .build(); //04 获得JobDataMap,写入数据 fillJobDataMap(trigger.getJobDataMap(),appQuartzDTO ); scheduler.scheduleJob(jobDetail,trigger); } catch (Exception e) { e.printStackTrace(); } } @Override public void pauseJob(String jobName, String jobGroupName) { try { scheduler.pauseJob(JobKey.jobKey(jobName,jobGroupName)); } catch (SchedulerException e) { e.printStackTrace(); } } @Override public void resumeJob(String jobName, String jobGroupName) { try { scheduler.resumeJob(JobKey.jobKey(jobName,jobGroupName)); } catch (SchedulerException e) { e.printStackTrace(); } } @Override public void modifyJob(AppQuartzDTO appQuartzDTO) { try { //01 根据任务名和任务组获取触发器Trigger TriggerKey triggerKey = TriggerKey.triggerKey(appQuartzDTO.getJobName(), appQuartzDTO.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //02 表达式调度构建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartzDTO.getCronExpression()); //03 按照新的CronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder() .withIdentity(triggerKey) .withSchedule(cronScheduleBuilder) .build(); //04 获得JobDataMap,写入数据 fillJobDataMap(trigger.getJobDataMap(),appQuartzDTO ); //05 按照新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey,trigger ); } catch (Exception e) { e.printStackTrace(); } } private void fillJobDataMap(JobDataMap jobDataMap,AppQuartzDTO appQuartzDTO){ jobDataMap.put(QuartzJobDataKey.CLASS_NAME,appQuartzDTO.getClassName() ); jobDataMap.put(QuartzJobDataKey.METHOD_NAME,appQuartzDTO.getMethodName() ); jobDataMap.put(QuartzJobDataKey.PARAMS,appQuartzDTO.getParams() ); jobDataMap.put(QuartzJobDataKey.CRON_EXPRESS,appQuartzDTO.getCronExpression() ); } /** * 根据类名称,通过反射得到该类; * @param classname * @throws Exception */ private static BaseJob getClass(String classname) throws Exception { Class<?> class1 = Class.forName(classname); return (BaseJob) class1.newInstance(); } }
5. Job 任务
(1)BaseJob
package com.ttbank.flep.job; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * @Author lucky * @Date 2022/4/6 9:27 */ public interface BaseJob extends Job { /** * 任务具体执行方法 * @param jobExecutionContext * @throws JobExecutionException */ @Override void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException; }
(2)ExecSdkJob
package com.ttbank.flep.job; import com.sun.media.jfxmedia.logging.Logger; import com.ttbank.flep.constant.QuartzJobDataKey; import lombok.extern.slf4j.Slf4j; import org.quartz.*; import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * @Author lucky * @Date 2022/4/6 10:12 */ @Slf4j @PersistJobDataAfterExecution @DisallowConcurrentExecution public class ExecSdkJob implements BaseJob { @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { JobDataMap jobDataMap = context.getTrigger().getJobDataMap(); String params = jobDataMap.getString(QuartzJobDataKey.PARAMS); log.info(params); FileOutputStream fileOutputStream=new FileOutputStream("D:\\data\\quartz_test01.txt",true); LocalDateTime localDateTime=LocalDateTime.now(); String currentTime = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh-mm-ss")); fileOutputStream.write(("当前时间为:"+currentTime+"\n").getBytes()); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }