spring boot 整合quartz并进行jdbc持久化

来源:互联网 发布:MySQL concat array 编辑:程序博客网 时间:2024/05/17 23:42

引言

quartz是什么在这里我就不接少了,想要了解的可以查看我的这篇介绍quartz的文章
http://blog.csdn.net/wujiaqi0921/article/details/78632760

在这里我们来接受一些spring与quartz的整合。

1.引入maven引用

        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz</artifactId>            <version>2.2.3</version>        </dependency>        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz-jobs</artifactId>            <version>2.2.3</version>        </dependency>

2.quartz配置类

spring boot建议去除配置文件的形式而改为bean暴露的形式,在这里我们我们以bean暴露的形式为例,当然你也可以选择配置文件的形式。
首先创建QuartzConfig.Java配置类。添加Configuration注解。具体代码如下:

package com.god.config;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.ee.servlet.QuartzInitializerListener;import org.quartz.impl.StdSchedulerFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.io.IOException;import java.util.Properties;/** * Created by wujiaqi on 17/11/6. */@Configurationpublic class QuartzConfig {    /**     * 设置调度工厂,并返回调度管理器     * 交由spring管理,使用时由autowire注入     * @return     * @throws IOException     * @throws SchedulerException     */    @Bean    public Scheduler schedule() throws  IOException, SchedulerException {        SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties());        Scheduler scheduler = schedulerFactory.getScheduler();        scheduler.start();        return scheduler;    }    /**     * 设置quartz属性     *     * @throws IOException     */    public static Properties quartzProperties() throws IOException {        Properties prop = new Properties();        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");//实例化threadPool时,使用的线程类为SimpleThreadPool        //threadCount和threadPriority将setter的形式注入ThreadPoolS实例        prop.put("org.quartz.threadPool.threadCount", "5");//并发数        prop.put("org.quartz.threadPool.threadPriority", "5");//优先级        prop.put("org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer", true);        //prop.put("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");//默认存储在内存中        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");//数据库持久化        prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");//        prop.put("org.quartz.jobStore.isClustered", false);//是否开启集群//        prop.put("org.quartz.jobStore.clusterCheckinInterval", 20000);//集群检查        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");//表前缀:true        prop.put("org.quartz.jobStore.dataSource", "mytest");//数据库        prop.put("org.quartz.dataSource.mytest.driver", "com.mysql.jdbc.Driver");        prop.put("org.quartz.dataSource.mytest.URL", "jdbc:mysql://localhost:3306/mytest?characterEncoding=UTF-8");        prop.put("org.quartz.dataSource.mytest.user", "root");        prop.put("org.quartz.dataSource.mytest.password", "root");        prop.put("org.quartz.dataSource.mytest.maxConnections", "10");        return prop;    }    /**     * 监听到工程的启动,在工程停止再启动时可以让已有的定时任务继续进行     *     * @return     */    @Bean    public QuartzInitializerListener quartzInitializerListener() {        return new QuartzInitializerListener();    }}

3.使用

我们在使用时,只需要交给spring注入就行了

    @Autowired    private Scheduler scheduler;

4.基于jdbc持久化的quartz使用

上面配置中采用了jdbc持久化的方式。sql建表代码如下,该代码由官方给出:

-- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar-- PLEASE consider using mysql with innodb tables to avoid locking issues-- In your Quartz properties file, you'll need to set-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegateDROP 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));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));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));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(200) 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));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));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),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));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));CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_GROUP  VARCHAR(200) NOT NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP));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));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));CREATE TABLE QRTZ_LOCKS  (    SCHED_NAME VARCHAR(120) NOT NULL,    LOCK_NAME  VARCHAR(40) NOT NULL,    PRIMARY KEY (SCHED_NAME,LOCK_NAME));commit;

接着我们来看一下使用过程:
这里写图片描述
我们可以看到当我们的程序启动之后,控制台会输出quartz相关信息。接着来看一下如何通过接口来创建我们的调度任务,代码如下,

package com.god.restController;import com.god.base.BaseRestService;import com.god.entity.TaskInfo;import org.quartz.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.ws.rs.Consumes;import javax.ws.rs.POST;import javax.ws.rs.Path;import javax.ws.rs.core.Response;/** * Created by wujiaqi on 17/11/19. */@Component@Path("/quartz")public class QuartzController extends BaseRestService{    @Autowired    private Scheduler scheduler;    @Path("addJob")    @Consumes(TYPE_JSON)    @POST    public Response addjob(TaskInfo job) throws Exception//String jobClassName, String jobGroupName, String cronExpression) throws Exception    {        try {//        QuartzFactory quartzFactory = new QuartzFactory();//        Scheduler scheduler = quartzFactory.schedule();            JobDetail jobDetail = JobBuilder.newJob(getClass(job.getJobClassName()).getClass())                    .withIdentity(job.getJobClassName(), job.getJobGroupName()).requestRecovery().build();            //创建表达式调度构建起            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());            //根据传入的cron表达式创建一个触发器            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobClassName(), job.getJobGroupName())                    .withSchedule(scheduleBuilder).build();            try {                scheduler.scheduleJob(jobDetail, trigger);            } catch (SchedulerException e) {                System.out.println("创建定时任务失败"+e);                throw new Exception("创建定时任务失败");            }            return buildSuccessMessage("success");        } catch (SchedulerException e) {            return buildFailMessage("failed");        }    }    @Path("pausejob")//    @Produces(TYPE_JSON)    @Consumes(TYPE_JSON)    @POST    public Response pausejob(TaskInfo job) throws Exception    {        scheduler.pauseJob(JobKey.jobKey(job.getJobClassName(), job.getJobGroupName()));        return buildSuccessMessage("success");    }    @Path("resumejob")//    @Produces(TYPE_JSON)    @POST    @Consumes(TYPE_JSON)    public Response resumejob(TaskInfo job) throws Exception    {        scheduler.resumeJob(JobKey.jobKey(job.getJobClassName(), job.getJobGroupName()));        return buildSuccessMessage("success");    }    @Path("rescheduleJob")//    @Produces(TYPE_JSON)    @POST    @Consumes(TYPE_JSON)    public Response rescheduleJob(TaskInfo job) throws Exception    {        try {            TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobClassName(), job.getJobGroupName());            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());            // 按新的cronExpression表达式重新构建trigger            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();            scheduler.rescheduleJob(triggerKey, trigger);            return buildSuccessMessage("success");        } catch (SchedulerException e) {            return buildFailMessage("failed");        }    }    @Path("deletejob")//    @Produces(TYPE_JSON)    @POST    @Consumes(TYPE_JSON)    public Response deletejob(TaskInfo job) throws Exception    {        try {            //暂停触发器            scheduler.pauseTrigger(TriggerKey.triggerKey(job.getJobClassName(), job.getJobGroupName()));            //暂停任务            scheduler.unscheduleJob(TriggerKey.triggerKey(job.getJobClassName(), job.getJobGroupName()));            //删除任务            scheduler.deleteJob(JobKey.jobKey(job.getJobClassName(), job.getJobGroupName()));            return buildSuccessMessage("success");        } catch (SchedulerException e) {            return buildFailMessage("faild");        }    }    public static Job getClass(String classname) throws Exception    {        String packageName = "com.god.quartz.";        classname = packageName.concat(classname);        Class<?> class1 = Class.forName(classname);        return (Job)class1.newInstance();    }}

相关job类:
HelloJob

package com.god.quartz;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.time.LocalTime;/** * Created by wujiaqi on 17/11/6. */public class HelloJob implements Job {    private static Logger logger = LoggerFactory.getLogger(HelloJob.class);    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        logger.info("hello jon执行时间: " + LocalTime.now());        System.out.println("hello jon执行时间: " + LocalTime.now());    }}

HiJob

package com.god.quartz;import org.quartz.DisallowConcurrentExecution;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.time.LocalTime;/** * Created by wujiaqi on 17/11/6. */@DisallowConcurrentExecutionpublic class HiJob implements Job {    private static Logger logger = LoggerFactory.getLogger(HiJob.class);    public HiJob() {    }    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        logger.info("hi jon 执行时间: " + LocalTime.now());    }}

上面我们可以看到我们根据任务名称来创建对应的Java实例。现在我们来调用一下创建任务的接口,我们通过postman来测试:
postman内容
接下来看一下测试结果:
这里写图片描述
我们可以看到控制台根据策略输出正确的信息。我们再来查询一下数据库

select * from QRTZ_JOB_DETAILS;

这里写图片描述
我们可以看到数据库中存储了我们创建的job信息。
好了,其他几个接口测试就不在这里展现了,已经过测试。以上就是一个简单的整合以及持久化过程。