Spring Boot Quartz 动态配置,持久化
Quartz 是一个很强大的任务调度框架在SpringBoot中也很容易集成
添加依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!--Quartz-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
数据源:我们需要实现一个接口 org.quartz.utils.ConnectionProvider 里面的方法跟 数据库连接池的方法比较相似,Quartz会帮助我们注入各种属性
一般情况下来说可以使用Druid或者C3p0数据源,不过我们项目中之前已经集成过C3p0就不必再创建连接池直接通过反射获取连接池实例即可,如图:connnectionProvider就是我们需要的
贴出主要代码:
package cc.stdpain.xxx.component;
import lombok.Data;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.c3p0.internal.C3P0ConnectionProvider;
import org.hibernate.internal.NonContextualJdbcConnectionAccess;
import org.hibernate.internal.SessionImpl;
import org.quartz.utils.ConnectionProvider;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;
@Data
public class QuartzC3p0ConnectionProvider implements ConnectionProvider {
//这些属性都会被注入,不过我们项目中已经有现成的连接池
//JDBC驱动
public String driver;
//JDBC连接串
public String URL;
//数据库用户名
public String user;
//数据库用户密码
public String password;
//数据库最大连接数
public int maxConnections;
//数据库SQL查询每次连接返回执行到连接池,以确保它仍然是有效的。
public String validationQuery;
private C3P0ConnectionProvider c3P0ConnectionProvider;
public QuartzC3p0ConnectionProvider() {
try {
Field sessionFactorField = MySqlClient.class.getDeclaredField("sessionFactory");
sessionFactorField.setAccessible(true);
SessionFactory sessionFactory = (SessionFactory) sessionFactorField.get(MySqlClient.class);
Session session = sessionFactory.openSession();
SessionImpl session1 = (SessionImpl) session;
NonContextualJdbcConnectionAccess connectionAccess = (NonContextualJdbcConnectionAccess) session1.getJdbcConnectionAccess();
Field providerField = connectionAccess.getClass().getDeclaredField("connectionProvider");
providerField.setAccessible(true);
c3P0ConnectionProvider = (C3P0ConnectionProvider) providerField.get(connectionAccess);
} catch (NoSuchFieldException e) {
e.printStackTrace();
System.exit(-1);
} catch (IllegalAccessException e) {
e.printStackTrace();
System.exit(-1);
}
}
@Override
public Connection getConnection() throws SQLException {
return c3P0ConnectionProvider.getConnection();
}
@Override
public void shutdown() throws SQLException {
c3P0ConnectionProvider.stop();
}
@Override
public void initialize() throws SQLException {
//因为我们的连接池已经初始化过了就不用在初始化了
}
}
application.properties 文件配置
#Quartz
org.quartz.scheduler.instanceName=MyScheduler
org.quartz.scheduler.instanceId=NON_CLUSTERED
org.quartz.scheduler.skip-update-check=false
org.quartz.scheduler.job-factory.class=org.quartz.simpl.SimpleJobFactory
## Quartz 线程池配置
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=1
#持久化配置
org.quartz.jobStore.misfireThreshold=50000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.datasource=quartzDataSource
org.quartz.jobStore.is-clustered=true
org.quartz.jobStore.tablePrefix=QRTZ_
#数据源
#这个Provider就是自己实现的那个类
org.quartz.dataSource.quartzDataSource.connection-provider=cc.stdpain.xxx.component.QuartzC3p0ConnectionProvider
#因为我们用的是现成的数据源,这些属性不要也罢不过为了以后方便配置,还是写上比较好
org.quartz.dataSource.quartzDataSource.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.quartzDataSource.URL=jdbc:mysql://{ip}:45150/{database}?useSSL=false
org.quartz.dataSource.quartzDataSource.user=test_user
org.quartz.dataSource.quartzDataSource.password=test_passwd
org.quartz.dataSource.quartzDataSource.maxConnections=5
org.quartz.dataSource.quartzDataSource.validationQuery=select 0
Bean配置
@Configuration
public class QuartzConfig {
@Autowired
AppConfig appConfig;
//因为数据源依赖MysqlClient中的SessionFactory
@DependsOn("mysqlClient")
@Bean
public Scheduler scheduler() throws IOException, SchedulerException {
SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties());
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
return scheduler;
}
@Bean
public Properties quartzProperties() throws IOException {
Properties prop = new Properties();
prop.put("quartz.scheduler.instanceName", appConfig.getQuartzSchedulerInstanceName());
prop.put("org.quartz.scheduler.instanceId", appConfig.getQuartzSchedulerInstanceId());
prop.put("org.quartz.scheduler.skipUpdateCheck", appConfig.getQuartzSchedulerSkipUpdateCheck());
prop.put("org.quartz.scheduler.jobFactory.class", appConfig.getQuartzSchedulerJobFactoryClass());
prop.put("org.quartz.jobStore.class", appConfig.getQuartzJobStoreClass());
prop.put("org.quartz.jobStore.driverDelegateClass", appConfig.getQuartzJobStoreDriverDelegateClass());
prop.put("org.quartz.jobStore.dataSource", appConfig.getQuartzJobStoreDatasource());
prop.put("org.quartz.jobStore.tablePrefix", appConfig.getQuartzJobStoreTablePrefix());
prop.put("org.quartz.jobStore.isClustered", appConfig.getQuartzJobStoreIsClustered());
prop.put("org.quartz.threadPool.class", appConfig.getQuartzThreadPoolClass());
prop.put("org.quartz.threadPool.threadCount", appConfig.getQuartzThreadPoolThreadCount());
prop.put("org.quartz.dataSource.quartzDataSource.connectionProvider.class", appConfig.getQuartzDataSourceQuartzDataSourceConnectionProvider());
prop.put("org.quartz.dataSource.quartzDataSource.driver", appConfig.getQuartzDatasourceQuartzDataSourceDriver());
prop.put("org.quartz.dataSource.quartzDataSource.URL", appConfig.getQuartzDatasourceQuartzDataSourceUrl());
prop.put("org.quartz.dataSource.quartzDataSource.user", appConfig.getQuartzDatasourceQuartzDataSourceUser());
prop.put("org.quartz.dataSource.quartzDataSource.password", appConfig.getQuartzDatasourceQuartzDataSourcePassword());
prop.put("org.quartz.dataSource.quartzDataSource.maxConnections", appConfig.getQuartzDatasourceQuartzDataSourceMaxConnections());
return prop;
}
}
数据库表结构
-- 如果不支持外键 使用 init2.sql
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;
我们任务的实体类
@Data
public class TaskEntity implements Serializable {
private final Long serialVersion = -12654128415L;
private Long id; //ID
private String jobName; //任务名称
private String jobGroup; //任务分组
private String jobStatus; //任务状态
private String jobClass;//任务执行方法
private String cronExpression; // cron 表达式
private String jobDescription; //任务描述
private String timeZoneId; // 时区
private Long startTime;
private Long endTime;
private String state; //状态
private String invokeParam;//调用参数
}
添加任务的话 只需要指定 jobName jobGroup jobClass cronExpression jobDescription invokeParam
@Slf4j
@Service
public class TaskService implements ITaskService {
@Autowired
private Scheduler scheduler;
@Override
public void addTask(TaskEntity taskEntity) {
String jobName = taskEntity.getJobName(),
jobGroup = taskEntity.getJobGroup(),
cronExpression = taskEntity.getCronExpression(),
jobDescription = taskEntity.getJobDescription();
String invokeParams = taskEntity.getInvokeParam();
try {
if (checkExists(jobName, jobGroup)) {
//error
}
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).
withDescription(jobDescription).withSchedule(scheduleBuilder).build();
trigger.getJobDataMap().put("invokeParam", invokeParams);
Class<? extends Job> clazz = (Class<? extends Job>) Class.forName(taskEntity.getJobClass());
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(jobDescription).build();
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException | ClassNotFoundException e) {
log.error("", e);
}
}
@Override
public void resumeTask(TaskEntity taskEntity) {
try {
scheduler.resumeJob(JobKey.jobKey(taskEntity.getJobName(), taskEntity.getJobGroup()));
} catch (Exception e) {
log.error("", e);
}
}
@Override
public void updateTask(TaskEntity info) {
String jobName = info.getJobName(),
jobGroup = info.getJobGroup(),
cronExpression = info.getCronExpression(),
jobDescription = info.getJobDescription(),
createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
try {
if (!checkExists(jobName, jobGroup)) {
//Error
}
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
JobKey jobKey = new JobKey(jobName, jobGroup);
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(cronScheduleBuilder).build();
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
jobDetail.getJobBuilder().withDescription(jobDescription);
Set<Trigger> triggerSet = new HashSet<>();
triggerSet.add(cronTrigger);
scheduler.scheduleJob(jobDetail, triggerSet, true);
} catch (SchedulerException e) {
log.error("", e);
}
}
@Override
public void pauseTask(TaskEntity taskEntity) {
TriggerKey triggerKey = TriggerKey.triggerKey(taskEntity.getJobName(), taskEntity.getJobGroup());
try {
if (checkExists(taskEntity.getJobName(), taskEntity.getJobGroup())) {
scheduler.pauseTrigger(triggerKey); //停止触发器
}
} catch (Exception e) {
log.error("", e);
}
}
@Override
public void deleteTask(TaskEntity taskEntity) {
TriggerKey triggerKey = TriggerKey.triggerKey(taskEntity.getJobName(), taskEntity.getJobGroup());
try {
if (checkExists(taskEntity.getJobName(), taskEntity.getJobGroup())) {
scheduler.pauseTrigger(triggerKey); //停止触发器
scheduler.unscheduleJob(triggerKey); //移除触发器
}
} catch (SchedulerException e) {
log.error("", e);
}
}
private boolean checkExists(String jobName, String jobGroup) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
return scheduler.checkExists(triggerKey);
}
}
任务状态查询
SELECT
QRTZ_JOB_DETAILS.JOB_NAME AS jobName,
QRTZ_JOB_DETAILS.JOB_GROUP AS jobGroup,
QRTZ_JOB_DETAILS.JOB_CLASS_NAME AS jobClass,
QRTZ_TRIGGERS.DESCRIPTION AS jobDescription,
QRTZ_TRIGGERS.TRIGGER_NAME AS triggerName,
QRTZ_TRIGGERS.TRIGGER_GROUP AS triggerGroup,
QRTZ_CRON_TRIGGERS.CRON_EXPRESSION AS cronExpression,
QRTZ_TRIGGERS.START_TIME AS startTime,
QRTZ_TRIGGERS.END_TIME AS endTime,
QRTZ_TRIGGERS.TRIGGER_STATE AS state,
QRTZ_CRON_TRIGGERS.TIME_ZONE_ID AS timeZoneId
FROM
QRTZ_JOB_DETAILS
JOIN QRTZ_TRIGGERS
JOIN QRTZ_CRON_TRIGGERS ON QRTZ_JOB_DETAILS.JOB_NAME = QRTZ_TRIGGERS.JOB_NAME
AND QRTZ_TRIGGERS.TRIGGER_NAME = QRTZ_CRON_TRIGGERS.TRIGGER_NAME
AND QRTZ_TRIGGERS.TRIGGER_GROUP = QRTZ_CRON_TRIGGERS.TRIGGER_GROUP
不过这样创建出来的 Job 声明周期不被Spring管理,因此无法使用依赖注入等,如果需要依赖注入支持还需要一些其他操作
对Jobs实现依赖注入
首先我们需要一个Job的工厂
@Component
@Slf4j
public class JobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
对Scheduler设置bean中的工厂
scheduler.setJobFactory(jobFactory);
然后创建Job的时候就可以依赖注入了
参考:https://yq.aliyun.com/articles/626199
Spring Boot Quartz 动态配置,持久化的更多相关文章
- Spring 与 Quartz 动态配置(数漫江湖)
因为项目的需求,需要有动态配置计划任务的功能.本文在 Quartz JobBean 中获取配置的 Quartz cronExpression 时间表达式及 Spring Bean 的对象名.方法名并运 ...
- Quartz 在 Spring 中如何动态配置时间--转
原文地址:http://www.iteye.com/topic/399980 在项目中有一个需求,需要灵活配置调度任务时间,并能自由启动或停止调度. 有关调度的实现我就第一就想到了Quartz这个开源 ...
- Quartz动态配置表达的方法
在项目中有一个需求,需要灵活配置调度任务时间,并能自由启动或停止调度.有关调度的实现我就第一就想到了Quartz这个开源调度组件,因为很多项目使用过,Spring结合Quartz静态配置调度任务时间, ...
- Spring Boot Quartz 分布式集群任务调度实现
Spring Boot Quartz 主要内容 Spring Scheduler 框架 Quartz 框架,功能强大,配置灵活 Quartz 集群 mysql 持久化定时任务脚本(tables_mys ...
- Spring Boot 2 (二):Spring Boot 2 动态 Banner
Spring Boot 2 (二):Spring Boot 2 动态 Banner Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner. 一.配置依赖 使用 Sp ...
- spring boot日志管理配置
spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如:Java Util Logging,Log4J,Log4J2和Logback.每种L ...
- 【转】spring boot application.properties 配置参数详情
multipart multipart.enabled 开启上传支持(默认:true) multipart.file-size-threshold: 大于该值的文件会被写到磁盘上 multipart. ...
- Spring boot quartz的相关资源
https://github.com/82253452/banner https://github.com/lvhao/schedule-job/tree/master/src/main/java/c ...
- Spring Boot的自动配置
Spring Boot的自动配置 --摘自https://www.hollischuang.com/archives/1791 随着Ruby.Groovy等动态语言的流行,相比较之下Java的开发显得 ...
随机推荐
- 1【西北师大-2108Java】第一次作业成绩汇总
[西北师大-2108Java]第一次作业成绩汇总 经过本次作业的练习,了解了Java最基本的知识和Java的发展:了解了Java到底是一门怎样的语言,也知道了学习Java的乐趣,懂得了去选择Java开 ...
- 【转】理解并设计rest/restful风格接口
网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信.这导致AP ...
- 【day05】php
一.时间日期函数库 1.安装:时间日期函数库PHPCORE组成部分 2. (1)date_default_timezone_set(string $timezone) 设置时区 ...
- 【BZOJ3876】[AHOI2014&JSOI2014] 支线剧情(无源汇有上下界网络流)
点此看题面 大致题意: 有一张\(DAG\),经过每条边有一定时间,从\(1\)号点出发,随时可以返回\(1\)号点,求经过所有边的最短时间. 无源汇有上下界网络流 这是无源汇有上下界网络流的板子题. ...
- nmap中文手册
译注该Nmap参考指南中文版由Fei Yang <fyang1024@gmail.com>和Lei Li<lilei_721@6611.org> 从英文版本翻译而来. 我们希望 ...
- 海边拾贝-C-面试篇
优秀的面试资料,不定期会更新: Leetcode上面别人整理的若干面试资料: https://github.com/huihut/interview 剑指offer:https://blog.csdn ...
- MyBatis-Generator 用法介绍
”工欲善其事,必先利其器“,古人说的很对,虽然不能做一个单纯的”工具帝“,但是自己有合适的工具集真的很关键.以前认识一个做逆向工程的高手,有自己的”反马套装“,其实不外乎就是 OD . IDA .Sy ...
- python中easydict的简单使用
easydict的作用:EasyDict可以使得以属性的方式去访问字典的值! 1. 实例1:获取字典的值 2. 实例2: 设置属性 3. 在深度学习中往往利用easydict建立一个全局的变量
- ASCll编码,
- CompletableService
public class CompletableServiceTest { public static void main(String[] args) throws ExecutionExcepti ...