打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Spring Boot整合Quartz持久化到数据库

获取Sql文件

http://www.quartz-scheduler.org/downloads/


解压获取的sql文件,并在数据库中执行

代码编写

引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <version>2.0.6.RELEASE</version>
    </dependency>
    <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>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.2</version>
    </dependency>
</dependencies>

quartz.properties (这里只配置了部分)
如果不想使用quartz.properties,文章末尾提供了yml配置,只需修改部分即可,其他的不变。

#=======================================================
#调度器配置
#=======================================================
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=project1QuartzScheduler
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
#=======================================================
#线程池配置
#=======================================================
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#=======================================================
#JobStore配置
#=======================================================
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.isClustered=false
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.dataSource=myDS
#=======================================================
#数据库配置
#=======================================================
org.quartz.dataSource.myDS.driver= com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL= jdbc:mysql:///quartz?characterEncoding=utf8&serverTimezone=UTC
org.quartz.dataSource.myDS.user= root
org.quartz.dataSource.myDS.password=151310
org.quartz.dataSource.myDS.maxConnections=5

这里给出大部分配置的详解(忽略了官方不推荐的配置)
官方配置

#========================================================================#
#                                 主配置                                 #
#========================================================================#
#调度器实例名称——用于在同一程序中使用多个实例时区分调度器#
#集群中同一调度器名称必须一致#
org.quartz.scheduler.instanceName
#调度器唯一,可以使用AUTO自动生成ID#
org.quartz.scheduler.instanceId
#可以实现InstanceIdGenerator接口,指定生成ID策略(instanceId需为AUTO)#
org.quartz.scheduler.instanceIdGenerator.class
#调度程序线程名称#
org.quartz.scheduler.threadName
#调度程序是否以守护线程运行#
org.quartz.scheduler.makeSchedulerThreadDaemon
#使用的JobFactory的类名#
org.quartz.scheduler.jobFactory.class
#调度程序节点一次允许获取(用于触发)的最大触发器数量#
org.quartz.scheduler.batchTriggerAcquisitionMaxCount
#========================================================================#
#                                线程池配置                              #
#========================================================================#
#使用的线程池实现的名称#
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#线程数#
org.quartz.threadPool.threadCount
#线程优先级,默认为5#
org.quartz.threadPool.threadPriority
#========================================================================#
#                             全局监视器配置                             #
#========================================================================#
org.quartz.triggerListener.NAME.class
org.quartz.triggerListener.NAME.propName
org.quartz.triggerListener.NAME.prop2Name
org.quartz.jobListener.NAME.class
org.quartz.jobListener.NAME.propName
org.quartz.jobListener.NAME.prop2Name
#========================================================================#
#                             RAMJobStore配置                            #
#========================================================================#
#将调度程序的JobStore设置为RAMJobStore#
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
#RAMJobStore可以通过下面属性进行调优#
#调度程序将容忍触发器通过下一次触发时间的毫秒数,然后才被认为是未触发,默认60000#
org.quartz.jobStore.misfireThreshold
#========================================================================#
#                           JDBC-JobStoreTX配置                          #
#========================================================================#
#驱动程序代表理解不同数据库系统的特定方言,许多数据库使用StdJDBCDelegate#
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#配置属性文件中定义的数据源的名称#
org.quartz.jobStore.dataSource
#Quartz表的前缀#
org.quartz.jobStore.tablePrefix
#JobDataMaps中的所有值都是字符串#
org.quartz.jobStore.useProperties
#调度程序将容忍触发器通过下一次触发时间的毫秒数,然后才被认为是未触发,默认60000#
org.quartz.jobStore.misfireThreshold
#是否为集群。如果多个Quartz实例使用同一数据库,必须为true,否则会造成严重破坏#
org.quartz.jobStore.isClustered
#此实例与集群的其他实例签入的频率(毫秒)。影响检测失败实例的速度#
org.quartz.jobStore.clusterCheckinInterval
#为true时Quartz在从数据源获得的连接上不要调用setAutoCommit(false)#
org.quartz.jobStore.dontSetAutoCommitFalse
#SQL字符串,它选择LOCKS表中的一行,并在该行上放置一个锁#
#默认SELECT * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ?#
#{0}:TABLE_PREFIX {1}:调度程序的名称
org.quartz.jobStore.selectWithLockSQL
#为true时Quartz在JDBC连接上调用setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)#
org.quartz.jobStore.txIsolationLevelSerializable
#========================================================================#
#                            DataSources配置                             #
#========================================================================#
#数据库JDBC驱动程序类#
org.quartz.dataSource.NAME.driver
#连接quartz数据库的url#
org.quartz.dataSource.NAME.URL
#用户名#
org.quartz.dataSource.NAME.user
#密码#
org.quartz.dataSource.NAME.password
#数据源创建的最大连接数#
org.quartz.dataSource.NAME.maxConnections

注意

  • myDS不要改
  • quartz是我的数据库,注意改为你的
  • QRTZ_是表的前缀

创建quartz配置文件

package com.dfyang.quartz.config;

import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class QuartzConfig {
@Autowired
private JobFactory jobFactory;

@Autowired
private AutowireCapableBeanFactory  capableBeanFactory;

/**
 * 当触发器触发时,与之关联的任务被Scheduler中配置的JobFactory实例化,也就是每触发一次,就会创建一个任务的实例化对象
 * (如果缺省)则调用Job类的newInstance方法生成一个实例
 * (这里选择自定义)并将创建的Job实例化交给IoC管理
 * @return
 */
@Bean
public JobFactory jobFactory() {
return new AdaptableJobFactory() {
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
};
}

@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(jobFactory);
//延迟启动
schedulerFactoryBean.setStartupDelay(1);
schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
return schedulerFactoryBean;
}

@Bean
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}

创建任务

package com.dfyang.quartz.controller;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class HelloJob extends QuartzJobBean {

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.err.println("hello world");
}
}

创建quartz-service接口

package com.dfyang.quartz.service;

import org.springframework.stereotype.Service;

@Service
public interface QuartzService {
    /**
     * 新增一个定时任务
     * @param jName 任务名称
     * @param jGroup 任务组
     * @param tName 触发器名称
     * @param tGroup 触发器组
     * @param cron cron表达式
     */
    void addJob(String jName, String jGroup, String tName, String tGroup, String cron);

    /**
     * 暂停定时任务
     * @param jName 任务名
     * @param jGroup 任务组
     */
    void pauseJob(String jName, String jGroup);

    /**
     * 继续定时任务
     * @param jName 任务名
     * @param jGroup 任务组
     */
    void resumeJob(String jName, String jGroup);

    /**
     * 删除定时任务
     * @param jName 任务名
     * @param jGroup 任务组
     */
    void deleteJob(String jName, String jGroup);
}

创建quartz-service实现

package com.dfyang.quartz.service.impl;

import com.dfyang.quartz.controller.HelloJob;
import com.dfyang.quartz.service.QuartzService;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class QuartzServiceImpl implements QuartzService {

    @Autowired
    private Scheduler scheduler;

    /**
     * 新增一个定时任务
     * @param jName 任务名称
     * @param jGroup 任务组
     * @param tName 触发器名称
     * @param tGroup 触发器组
     * @param cron cron表达式
     */
    @Override
    public void addJob(String jName, String jGroup, String tName, String tGroup, String cron) {
        try {
            JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                    .withIdentity(jName, jGroup)
                    .build();
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(tName, tGroup)
                    .startNow()
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                    .build();
            scheduler.start();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 暂停定时任务
     * @param jName 任务名
     * @param jGroup 任务组
     */
    @Override
    public void pauseJob(String jName, String jGroup) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jName, jGroup));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 继续定时任务
     * @param jName 任务名
     * @param jGroup 任务组
     */
    @Override
    public void resumeJob(String jName, String jGroup) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jName, jGroup));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除定时任务
     * @param jName 任务名
     * @param jGroup 任务组
     */
    @Override
    public void deleteJob(String jName, String jGroup) {
        try {
            scheduler.deleteJob(JobKey.jobKey(jName, jGroup));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

创建测试controller

package com.dfyang.quartz.controller;

import com.dfyang.quartz.service.QuartzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class QuartzController {

    @Autowired
    private QuartzService quartzService;

    /**
     * 新增任务
     */
    @GetMapping("/insert")
    public String insertTask(String jName, String jGroup, String tName, String tGroup, String cron) {
        quartzService.addJob(jName, jGroup, tName, tGroup, cron);
        return "添加成功!";
    }

    /**
     * 暂停任务
     */
    @GetMapping("/pause")
    public String pauseTask(String jName, String jGroup) {
        quartzService.pauseJob(jName, jGroup);
        return "暂停成功!";
    }

    /**
     * 继续任务
     */
    @GetMapping("/resume")
    public String resumeTask(String jName, String jGroup) {
        quartzService.resumeJob(jName, jGroup);
        return "继续成功!";
    }

    /**
     * 删除任务
     */
    @GetMapping("/delete")
    public String deleteTask(String jName, String jGroup) {
        quartzService.deleteJob(jName, jGroup);
        return "删除成功!";
    }

}

启动项目


测试新增
http://localhost:8080/insert?jName=testJob&jGroup=test&tName=testTrigger&tGroup=test&cron=0,10,20,30,40,50 * * * * ?




如果重新启动项目,这时创建的任务仍然能够执行,因为已经持久化到了数据库。
其他可以自行测试,因为测试简单,这里没写了。

另一种配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/quartz?characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=151310
spring.quartz.properties.org.quartz.scheduler.instanceName=DefaultQuartzScheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.properties.org.quartz.scheduler.rmi.export=false
spring.quartz.properties.org.quartz.scheduler.rmi.proxy=false
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.jobStore.isClustered=false
spring.quartz.properties.org.quartz.jobStore.useProperties=false
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.threadCount=10
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
spring.quartz.properties.org.quartz.dataSource.myDS.URL=jdbc:mysql:///quartz?characterEncoding=utf8&serverTimezone=UTC
spring.quartz.properties.org.quartz.dataSource.myDS.user=root
spring.quartz.properties.org.quartz.dataSource.myDS.password=151310
spring.quartz.properties.org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
spring.quartz.properties.org.quartz.dataSource.myDS.maxConnections=5
spring.quartz.job-store-type=jdbc

最后把config中使用配置文件去掉即可,其他的可以不用改。

package com.dfyang.quartz.config;

import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class QuartzConfig {
@Autowired
private JobFactory jobFactory;

@Autowired
private AutowireCapableBeanFactory  capableBeanFactory;

/**
 * 当触发器触发时,与之关联的任务被Scheduler中配置的JobFactory实例化,也就是每触发一次,就会创建一个任务的实例化对象
 * (如果缺省)则调用Job类的newInstance方法生成一个实例
 * (这里选择自定义)并将创建的Job实例化交给IoC管理
 * @return
 */
@Bean
public JobFactory jobFactory() {
return new AdaptableJobFactory() {
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
};
}

@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(jobFactory);
//延迟启动
schedulerFactoryBean.setStartupDelay(1);
return schedulerFactoryBean;
}

@Bean
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
使用 SpringBoot2.X 实现 Quartz 动态任务的分布式调度
quartz持久化实现
Quartz 定时任务管理类
SpringBoot之旅
springboot之使用redistemplate优雅地操作redis
Java docx4j 操作word 1.0
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服