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的时候就可以依赖注入了