SpringBoot2.0整合Quartz(JDBC)+Druid连接池遇到的一些坑

背景

第一次写文章,可能写的不是很好,如果大家有问题可以提出来!


最近我在研究定时任务的时候,看了好多都不太合适,在做完一个ScheduleThreadPoolExecutor的demo后,就遇到了Quartz这个任务调度框架,如题我现在是想把Spring Boot与Quartz整合,同时用Druid替换掉自带的C3P0连接池。
于是在这里就遇到问题了,我在网上找到的文章不是没有用SpringBoot的就是用了SpringBoot没有用Druid连接池的,还有就是用了SpringBoot和Druid,但是没有给详细配置信息的,于是我觉得写下这篇文章记录一下遇到的这些坑。

Springboot2.7.2集成Quartz+Druid

整合Quartz主要分为两步,引入依赖和写好配置文件即可,如果要引入Druid连接池,就还需要再写一个连接池的配置类,本文介绍的是引入Druid连接池的情况。
本次Quartz采用的是JDBC连接方式,相关Sql文件去官网下源码,在源码的包中

引入依赖

<!--Quartz任务调度框架-->
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
    <version>2.7.2</version>
</dependency>
<!--druid连接池-->
<dependency>
	<groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.11</version>
</dependency>

application.yml配置文件

server:
  port: 8080
spring:
  application:
    name: quartz
  quartz:
    #数据库方式
    job-store-type: jdbc
    #相关属性配置
    properties:
      org:
        quartz:
          scheduler:
            instanceName: DefaultQuartzScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_
            #自定义的数据源别名,与最下方一致
            dataSource: qzDB
            #与cron的调度有关,忽略重启期间的任务
            misfireThreshold: 1000
            #设置为true开启集群
            isClustered: false
            clusterCheckinInterval: 10000
            #如果开启,会没法给任务传参数
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true
          dataSource:
            qzDB:
            #这里是坑点了,这个Druild连接类要自己提供,本文会在下方提供
              connectionProvider.class: com.xxxxxxx.DruidConnectionProvider
              maxConnection: 10
              driver: com.mysql.cj.jdbc.Driver
              URL: jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&autoReconnect-true&useSSL=false&serverTimezone=Asia/Shanghai
              user: xxx
              password: xxx

Druid连接池配置类

在上方的yml配置文件中,最后面有一个connectionProvider.class: com.xxxxxxx.DruidConnectionProvider,没错!这个就是自己要提供的连接池配置类,之前看过好多文章在这里都是一笔带过了,坑了好久。
把这个类实现一下就ok了,具体如下:

@Data
public class DruidConnectionProvider implements ConnectionProvider {
    //常量配置,需提供set方法,Quartz框架自动注入值。(这里用了Lombok的@Data,会自动生成getter和setter)
    /**
     * JDBC驱动
     */
    public String driver;
    /**
     * JDBC连接串,必须是URL
     */
    public String URL;
    /**
     * 数据库用户名,不是username
     */
    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;

    //接口实现

    @Override
    public Connection getConnection() throws SQLException {
        return datasource.getConnection();
    }

    @Override
    public void shutdown() {
        datasource.close();
    }

    @Override
    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 maxConnections 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 ignored) {
            }
        }
        datasource.setUrl(this.URL);
        datasource.setUsername(this.user);
        datasource.setPassword(this.password);
        datasource.setMaxActive(this.maxConnection);
        datasource.setMinIdle(1);
        datasource.setMaxWait(0);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(DEFAULT_DB_MAX_CONNECTIONS);
        if (this.validationQuery != null) {
            datasource.setValidationQuery(this.validationQuery);
            if (!this.validateOnCheckout) {
                datasource.setTestOnReturn(true);
            } else {
                datasource.setTestOnBorrow(true);
            }
            datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);
        }
    }
}

最后

到这里之后就已经完成了SpringBoot与Quartz以及Druid连接池的整合,如果有问题就直接问嗷!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是整合步骤: 1. 在 pom.xml 中添加依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.21</version> </dependency> ``` 2. 在 application.yml 或 application.properties 文件中配置数据源和 Quartz: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/db_name?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver quartz: job-store-type: jdbc jdbc: initialize-schema: never # 默认值为 always,表示每次启动都会重新初始化表结构,这里设为 never,只在第一次启动时初始化 ``` 3. 创建一个 Quartz 配置类,用于配置 Quartz 的属性: ```java @Configuration public class QuartzConfig { @Autowired private DataSource dataSource; @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setDataSource(dataSource); schedulerFactoryBean.setQuartzProperties(quartzProperties()); schedulerFactoryBean.setSchedulerName("MyScheduler"); schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext"); schedulerFactoryBean.setAutoStartup(true); schedulerFactoryBean.setStartupDelay(5); return schedulerFactoryBean; } @Bean public Properties quartzProperties() { Properties properties = new Properties(); properties.setProperty("org.quartz.scheduler.instanceName", "MyScheduler"); properties.setProperty("org.quartz.scheduler.instanceId", "AUTO"); properties.setProperty("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX"); properties.setProperty("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate"); properties.setProperty("org.quartz.jobStore.useProperties", "false"); properties.setProperty("org.quartz.jobStore.dataSource", "myDS"); properties.setProperty("org.quartz.jobStore.tablePrefix", "QRTZ_"); properties.setProperty("org.quartz.jobStore.isClustered", "true"); properties.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); properties.setProperty("org.quartz.threadPool.threadCount", "10"); properties.setProperty("org.quartz.dataSource.myDS.driver", "com.mysql.jdbc.Driver"); properties.setProperty("org.quartz.dataSource.myDS.URL", "jdbc:mysql://localhost:3306/db_name?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"); properties.setProperty("org.quartz.dataSource.myDS.user", "root"); properties.setProperty("org.quartz.dataSource.myDS.password", "123456"); properties.setProperty("org.quartz.dataSource.myDS.maxConnections", "10"); return properties; } } ``` 4. 创建一个 Job 类,用于定义具体的任务: ```java public class MyJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 任务执行逻辑 } } ``` 5. 创建一个 Trigger 类,用于定义任务执行的时间规则: ```java public class MyTrigger { public static Trigger getTrigger() { SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) // 每 10 秒执行一次 .repeatForever(); return TriggerBuilder.newTrigger() .withIdentity("MyTrigger", "MyTriggerGroup") .withSchedule(scheduleBuilder) .startAt(new Date()) // 从当前时间开始执行 .build(); } } ``` 6. 在启动类中添加注解 @EnableScheduling,用于开启定时任务: ```java @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 7. 在需要调度任务的地方,注入 Scheduler 对象,然后调用其 scheduleJob 方法即可: ```java @Autowired private Scheduler scheduler; public void scheduleJob() throws SchedulerException { JobDetail jobDetail = JobBuilder.newJob(MyJob.class) .withIdentity("MyJob", "MyJobGroup") .build(); Trigger trigger = MyTrigger.getTrigger(); scheduler.scheduleJob(jobDetail, trigger); } ``` 以上就是 Spring Boot 整合 QuartzDruid 的步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值