springboot与quartz整合

本文详细介绍了如何在SpringBoot中整合Quartz定时任务框架,包括从数据库读取表达式启动任务、更改任务状态、传递参数以及调整任务执行规则。通过自定义配置和作业工厂,实现了动态管理和监控定时任务。
摘要由CSDN通过智能技术生成

目录

1、Spring整合Quartz
2、读取数据库中表达式启动定时任务1(每5s执行)
3、更改定时任务状态(启用/禁用),定时任务1停止
4、读取数据库中表达式启动定时任务2(每5s执行),在对应作业类中打印定时任务2携带的参数
读取数据库中表达式启动定时任务3(每5s执行改成每20s执行),更改数据库定时任务表达式,定时任务3对应执行策略相应发生改变。

Spring整合Quartz

a、quartz调度框架是有内置表的
进入quartz的官网link,点击Downloads,
下载后在目录\docs\dbTables下有常用数据库创建quartz表的脚本,例如:“tables_mysql.sql”

table_mysql.sql
table_mysql_innodb.sql
上述两者所有的数据库引擎不一样

b、导入pom依赖

<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz-jobs</artifactId>
	<version>2.2.1</version>
   </dependency>
   <dependency>
   	<groupId>org.springframework.boot</groupId>
   	<artifactId>spring-boot-starter-quartz</artifactId>
   </dependency>
   <!--quartz需要使用C3P0连接池将数据持久化到数据库-->
   <!--Quartz各版本数据库连接池技术更新情况-->
   <!--Quartz 2.0 以前 DBCP-->
   <!--Quartz 2.0 以后 C3P0(包含2.0)-->
   <dependency>
   	<groupId>com.mchange</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.5.2</version>
   </dependency>

   更换成Druid连接池

   A、 引入依赖

   <dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.1.10</version>
   </dependency>

   B、 导入DruidConnectionProvider.java

C、修改quartz.properties配置

#配置数据库源
org.quartz.dataSource.qzDS.connectionProvider.class:
com.lyl.项目名.util.DruidConnectionProvider

c、在项目中添加quartz.properties文件(这样就不会加载自带的properties文件)
此文件的内容主要分为:scheduler,ThreadPool,JobStore,plugin,Datasources等部分,
覆盖properties文件的目的是覆盖默认的数据源,更换为druid的数据配置

d、自定义MyJobFactory,解决spring不能在quartz中注入bean的问题
e、创建调度器schedule,交给spring进行管理
f、创建自定义任务
g、更新quartz中的任务
自定义任务表与quartz内置表的区分

要搞清楚一个问题:从数据库读取任务信息动态生成定时任务,和把quartz持久化到数据库是没有关系的。前者是我们自己定义的业务表,而后者是quartz使用自己的表来存储信息。持久化到数据库后,就算服务器重启或是多个quartz节点也没关系,因为他们共享数据库中的任务信息。

在这里插入图片描述
自定义的业务表

-- 注意:job_name存放的任务类的全路径,在quartz中通过jobName和jobGroup来确定trigger的唯一性,所以这两列为联合唯一索引
create table t_schedule_trigger
(
  id int primary key auto_increment,                                -- ID
  cron varchar(200) not null,                                       -- 时间表达式
  status char(1) not null,                                          -- 使用状态 0:禁用   1:启用
  job_name varchar(200) not null,                                   -- 任务名称
  job_group varchar(200) not null,                                  -- 任务分组  
  unique index(job_name,job_group)
);

-- 额外添加到任务中的参数
create table t_schedule_trigger_param
(
  param_id int primary key auto_increment,                                -- ID
  name varchar(200) not null,                                             -- 参数名
  value varchar(512),                                                     -- 参数值
 
  schedule_trigger_id int not null,                                       -- 外键:引用t_schedule_trigger(id)
  foreign key(schedule_trigger_id) references t_schedule_trigger(id)
);

DruidConnectionProvider.java

package com.lyl.quartz02.utils;

import com.alibaba.druid.pool.DruidDataSource;
import org.quartz.SchedulerException;
import org.quartz.utils.ConnectionProvider;

import java.sql.Connection;
import java.sql.SQLException;

/*
#============================================================================
# JDBC
#============================================================================
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:false
org.quartz.jobStore.dataSource:qzDS
#org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider
org.quartz.dataSource.qzDS.connectionProvider.class:com.zking.q03.quartz.DruidConnectionProvider
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root
org.quartz.dataSource.qzDS.maxConnections:30
org.quartz.dataSource.qzDS.validationQuery: select 0
*/

/**
 * [Druid连接池的Quartz扩展类]
 *
 * @ProjectName: []
 * @Author: [xuguang]
 * @CreateDate: [2015/11/10 17:58]
 * @Update: [说明本次修改内容] BY[xuguang][2015/11/10]
 * @Version: [v1.0]
 */
public class DruidConnectionProvider implements ConnectionProvider {
   

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * 常量配置,与quartz.properties文件的key保持一致(去掉前缀),同时提供set方法,Quartz框架自动注入值。
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    //JDBC驱动
    public String driver;
    //JDBC连接串
    public String URL;
    //数据库用户名
    public String user;
    //数据库用户密码
    public String password;
    //数据库最大连接数
    public int maxConnection;
    //数据库SQL查询每次连接返回执行到连接池,以确保它仍然是有效的。
    public String validationQuery;

    private boolean validateOnCheckout;

    private int idleConnectionValidationSeconds;

    public String maxCachedStatementsPerConnection;

    private String discardIdleConnectionsSeconds;

    public static final int DEFAULT_DB_MAX_CONNECTIONS = 10;

    public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;

    //Druid连接池
    private DruidDataSource datasource;

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * 接口实现
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    public Connection getConnection() throws SQLException {
   
        return datasource.getConnection();
    }

    public void shutdown() throws SQLException {
   
        datasource.close();
    }
    public void initialize() throws SQLException{
   
        if (this.URL == null) {
   
            throw new SQLException("DBPool could not be created: DB URL cannot be null");
        }

        if (this.driver == null) {
   
            throw new SQLException("DBPool driver could not be created: DB driver class name cannot be null!");
        }

        if (this.maxConnection < 0) {
   
            throw new SQLException("DBPool maxConnectins could not be created: Max connections must be greater than zero!");
        }

        datasource = new DruidDataSource();
        try{
   
            datasource.setDriverClassName(this.driver);
        } catch (Exception e) {
   
            try {
   
                throw new SchedulerException("Problem setting driver class name on datasource: " + e.getMessage(), e);
            } catch (SchedulerException e1) {
   
            }
        }

        datasource.setUrl(this.URL);
        datasource.setUsername(this.user);
        datasource.setPassword(this.password);
        datasource.setMaxActive(this.maxConnection);
        datasource.setMinIdle(1);
        datasource.setMaxWait(0);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(this.DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION);

        if (this.validationQuery != null) {
   
            datasource.setValidationQuery(this.validationQuery);
            if(!this.validateOnCheckout)
                datasource.setTestOnReturn(true);
            else
                datasource.setTestOnBorrow(true);
            datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);
        }
    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * 提供get set方法
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    public String getDriver() {
   
        return driver;
    }

    public void setDriver(String driver) {
   
        this.driver = driver;
    }

    public String getURL() {
   
        return URL;
    }

    public void setURL(String URL) {
   
        this.URL = URL;
    }

    public String getUser() {
   
        return user;
    }

    public void setUser(String user) {
   
        this.user = user;
    }

    public String getPassword() {
   
        return password;
    }

    public void setPassword(String password) {
   
        this.password = password;
    }

    public int getMaxConnection() {
   
        return maxConnection;
    }

    public void setMaxConnection(int maxConnection) {
   
        this.maxConnection = maxConnection;
    }

    public String getValidationQuery() {
   
        return validationQuery;
    }

    public void setValidationQuery(String validationQuery) {
   
        this.validationQuery = validationQuery;
    }

    public boolean isValidateOnCheckout() {
   
        return validateOnCheckout;
    }

    public void setValidateOnCheckout(boolean validateOnCheckout) {
   
        this.validateOnCheckout = validateOnCheckout;
    }

    public int getIdleConnectionValidationSeconds() {
   
        return idleConnectionValidationSeconds;
    }

    public void setIdleConnectionValidationSeconds(int idleConnectionValidationSeconds) {
   
        this.idleConnectionValidationSeconds = idleConnectionValidationSeconds;
    }

    public DruidDataSource getDatasource() {
   
        return datasource;
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。 Quartz的优势: 1、Quartz是一个任务调度框架(库),它几乎可以集成到任何应用系统中。 2、Quartz是非常灵活的,它让您能够以最“自然”的方式来编写您的项目的代码,实现您所期望的行为 3、Quartz是非常轻量级的,只需要非常少的配置 —— 它实际上可以被跳出框架来使用,如果你的需求是一些相对基本的简单的需求的话。 4、Quartz具有容错机制,并且可以在重启服务的时候持久化(”记忆”)你的定时任务,你的任务也不会丢失。 5、可以通过Quartz,封装成自己的分布式任务调度,实现强大的功能,成为自己的产品。6、有很多的互联网公司也都在使用Quartz。比如美团 Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度。   课程说明:在我们的日常开发中,各种大型系统的开发少不了任务调度,简单的单机任务调度已经满足不了我们的系统需求,复杂的任务会让程序猿头疼, 所以急需一套专门的框架帮助我们去管理定时任务,并且可以在多台机器去执行我们的任务,还要可以管理我们的分布式定时任务。本课程从Quartz框架讲起,由浅到深,从使用到结构分析,再到源码分析,深入解析Quartz、Spring+Quartz,并且会讲解相关原理, 让大家充分的理解这个框架和框架的设计思想。由于互联网的复杂性,为了满足我们特定的需求,需要对Spring+Quartz进行二次开发,整个二次开发过程都会进行讲解。Spring被用在了越来越多的项目中, Quartz也被公认为是比较好用的定时器设置工具,学完这个课程后,不仅仅可以熟练掌握分布式定时任务,还可以深入理解大型框架的设计思想。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值