springboot2.7.11 + quartz2.3.2,单机,集群实战,增删改查任务,项目一启动就执行任务

在 IT 基础设施管理中,网络设备配置定时备份是保障运维安全的核心需求(避免配置丢失、支持故障回滚)。本文基于 Spring Boot 2.x 环境,详细讲解如何整合 Quartz 实现动态任务调度,解决数据源配置、任务增删改查、Spring Bean 注入等关键问题,附完整可复用代码。

一、环境准备与核心依赖

1. 技术栈选型

  • 基础框架:Spring Boot 2.x
  • 任务调度:Quartz 2.3.x(Spring Boot Starter 集成)
  • 数据源:Druid 连接池 + MySQL 8.0
  • 工具类:Hutool(JSON 序列化/反序列化)
  • 其他:Spring WebSecurity(权限控制,可选)
    手动执行 Quartz 建表脚本(路径:quartz-core-2.3.x.jar!/org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql

2. Maven 核心依赖

pom.xml 中引入 Quartz Starter 及 Druid 依赖(已集成的可忽略):

<!-- Quartz 任务调度 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

<!-- Druid 数据源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.16</version> <!-- 版本可按需调整 -->
</dependency>

<!-- MySQL 驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Hutool 工具类(JSON 处理) -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.22</version>
</dependency>

二、Quartz 核心配置(解决数据源与 Bean 注入问题)

Quartz 默认不依赖 Spring 数据源,且 Job 实例无法直接注入 Spring Bean(如 Mapper/Service)。以下配置从 数据源绑定Spring 上下文集成 两方面解决核心痛点。

1. 自定义 Quartz 数据源提供者

手动将 Druid 数据源注入 Quartz,避免 Quartz 找不到数据源的问题:

import com.alibaba.druid.pool.DruidDataSource;
import org.quartz.utils.ConnectionProvider;
import org.springframework.stereotype.Component;

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

/**
 * Quartz 自定义数据源提供者(绑定 Druid 数据源)
 */
@Component
public class DruidQuartzConnectionProvider implements ConnectionProvider {
   
   

    private final DruidDataSource dataSource;

    // 构造器注入 Spring 管理的 Druid 数据源
    public DruidQuartzConnectionProvider(DruidDataSource dataSource) {
   
   
        this.dataSource = dataSource;
    }

    @Override
    public Connection getConnection() throws SQLException {
   
   
        // 直接从 Druid 连接池获取连接
        return dataSource.getConnection();
    }

    @Override
    public void shutdown() {
   
   
        // 数据源由 Spring 管理,无需手动关闭
    }

    @Override
    public void initialize() throws SQLException {
   
   
        // 避免重复初始化(依赖 Spring 初始化 Druid)
    }
}

2. Quartz 核心配置类

配置 Scheduler 工厂、任务工厂(支持 Spring Bean 注入)、Quartz 集群属性:

import com.alibaba.druid.pool.DruidDataSource;
import org.quartz.Scheduler;
import org.quartz.spi.TriggerFiredBundle;
import org.quartz.utils.DBConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.annotation.PostConstruct;
import java.util.Properties;

/**
 * Quartz 核心配置类(数据源绑定 + 任务工厂配置)
 */
@Configuration
@Order(1) // 确保配置优先加载
public class QuartzConfig {
   
   

    @Autowired
    private DruidDataSource dataSource;

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 初始化 Quartz 数据源(解决 Quartz 找不到数据源问题)
     */
    @PostConstruct
    public void initDataSourceProvider() {
   
   
        DBConnectionManager.getInstance()
                .addConnectionProvider("druidDataSource", new DruidQuartzConnectionProvider(dataSource));
    }

    /**
     * 配置 Scheduler 工厂(核心)
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
   
   
        SchedulerFactoryBean factory = new SchedulerFactoryBean();

        // 1. 绑定数据源
        factory.setDataSource(dataSource);
        // 2. 配置 Quartz 属性(集群 + 线程池)
        factory.setQuartzProperties(quartzProperties());
        // 3. 应用启动时自动启动调度器
        factory.setAutoStartup(true);
        // 4. 覆盖已存在的任务(避免重复)
        factory.setOverwriteExistingJobs(true);

        // 5. 关键:配置 Job 工厂,支持 Spring Bean 注入
        ConfigurableApplicationContext configurableContext = (ConfigurableApplicationContext) applicationContext;
        AutowireCapableBeanFactory autowireBeanFactory = configurableContext.getAutowireCapableBeanFactory();
        
        factory.setJobFactory(new AdaptableJobFactory() {
   
   
            @Override
            protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
   
   
                // 第一步:Quartz 默认创建 Job 实例
                Object jobInstance = super.createJobInstance(bundle);
                // 第二步:Spring 自动注入 Job 中的 Bean(如 Mapper/Service)
                autowireBeanFactory.autowireBean(jobInstance);
                return jobInstance;
            }
        });

        return factory;
    }

    /**
     * 注册 Scheduler 实例(供业务代码调用)
     */
    @Bean
    public Scheduler scheduler(SchedulerFactoryBean factory) {
   
   
        return factory.getScheduler();
    }

    /**
     * Quartz 核心属性配置(集群模式 + 线程池)
     */
    private Properties quartzProperties() {
   
   
        Properties properties = new Properties();
        // 调度器实例名(集群内统一)
        properties.setProperty("org.quartz.scheduler.instanceName", "NetDeviceBackupScheduler");
        // 实例 ID 自动生成(集群模式必备)
        properties.setProperty("org.quartz.scheduler.instanceId", "AUTO");
        // 线程池配置(25 个线程,优先级 5)
        properties.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        properties.setProperty("org.quartz.threadPool.threadCount", "25");
        properties.setProperty("org.quartz.threadPool.threadPriority", "5");
        // 持久化配置(JDBC 存储,支持集群)
        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.tablePrefix", "QRTZ_"); // 数据库表前缀
        properties.setProperty("org.quartz.jobStore.isClustered", "true"); // 启用集群
        properties.setProperty("org.quartz.jobStore.clusterCheckinInterval", "20000"); // 集群
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值