首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring 整合 Quartz 實戰:聲明式定時任務配置全指南

     編輯:Java 綜合教學

在 Spring 容器中優雅使用 Quartz:FactoryBean 模式零侵入業務代碼

Quartz 是 Java 領域功能最強大的調度框架,Spring 通過 SchedulerFactoryBean、MethodInvokingJobDetailFactoryBean、CronTriggerFactoryBean 等 FactoryBean 將其無縫納入 IoC 容器。本文展示純 XML 配置實現「目標類無需實現 Job 接口」的鬆耦合定時任務,並解析啟動延遲、線程池、Cron 表達式等關鍵參數。

一、目標類:純 POJO,零 Quartz 依賴

public class MyJob2 {
    public void targetMethod() {
        System.out.println("hello world, quartz, date:" + new Date());
    }
}

二、Spring-Quartz.xml 完整配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://www.springframework.org/schema/beans
                           https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 1. 目標 Bean -->
    <bean id="myJob" class="com.nucsoft.quartz.job.MyJob2"/>

    <!-- 2. JobDetail:綁定目標對象與方法 -->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="myJob"/>
        <property name="targetMethod" value="targetMethod"/>
    </bean>

    <!-- 3. CronTrigger:指定 JobDetail 與 Cron 表達式 -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetail"/>
        <!-- 每 5 秒執行一次 -->
        <property name="cronExpression" value="0/5 * * * * ?"/>
    </bean>

    <!-- 4. Scheduler:註冊 Trigger、配置線程池、啟動延遲 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <array><ref bean="cronTrigger"/></array>
        </property>
        <!-- Quartz 底層屬性覆蓋 -->
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.threadPool.threadCount">10</prop>
            </props>
        </property>
        <!-- 容器啟動 10 秒後啟動調度器,避免與業務啟動衝突 -->
        <property name="startupDelay" value="10"/>
    </bean>
</beans>

三、核心組件解析

FactoryBean職責關鍵屬性
MethodInvokingJobDetailFactoryBean將 POJO 方法包裝為 Quartz JobDetailtargetObject, targetMethod, concurrent(false 默認串行)
CronTriggerFactoryBean構建基於 Cron 表達式的 TriggerjobDetail, cronExpression, startTime, timezone
SimpleTriggerFactoryBean構建固定頻率/延遲 TriggerjobDetail, repeatInterval, repeatCount, startDelay
SchedulerFactoryBean創建並啟動 Quartz Scheduler,註冊 Triggertriggers, quartzProperties, startupDelay, schedulerName

四、Cron 表達式速查

* * * * * * ?
秒 分 時 日 月 周 年(可選)
0/5 * * * * ?     每 5 秒
0 0/1 * * * ?     每 1 分鐘
0 0 2 * * ?       每天 02:00
0 0 2 ? * MON-FRI 工作日 02:00
0 0 2 1 * ?       每月 1 號 02:00
0 0 2 L * ?       每月最後一天 02:00

五、啟動測試

public class QuartzTest {
    public static void main(String[] args) {
        // 僅啟動 Spring 容器,Scheduler 自動啟動
        new ClassPathXmlApplicationContext("spring-quartz.xml");
    }
}

關鍵現象:首次執行時間 = 容器啟動 + startupDelay;第二次執行才按 Cron 間隔。因為首次是「啟動調度器」,非「觸發任務」。

六、進階:持久化集群模式

<property name="quartzProperties">
    <props>
        <prop key="org.quartz.scheduler.instanceName">MyCluster</prop>
        <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
        <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
        <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
        <prop key="org.quartz.jobStore.dataSource">myDS</prop>
        <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
        <prop key="org.quartz.jobStore.isClustered">true</prop>
        <prop key="org.quartz.dataSource.myDS.driver">com.mysql.jdbc.Driver</prop>
        <prop key="org.quartz.dataSource.myDS.URL">jdbc:mysql://...</prop>
        <prop key="org.quartz.dataSource.myDS.user">root</prop>
        <prop key="org.quartz.dataSource.myDS.password">pwd</prop>
        <prop key="org.quartz.dataSource.myDS.maxConnections">20</prop>
    </props>
</property>
<property name="dataSource" ref="dataSource"/> <!-- 引用 Spring DataSource -->
<property name="transactionManager" ref="transactionManager"/>

集群模式下多節點共享數據庫表,自動實現負載均衡與故障轉移。

七、Spring Boot 2.x+ 簡化配置

@Configuration
@EnableScheduling
public class QuartzConfig {
    @Bean
    public JobDetail jobDetail() {
        return JobBuilder.newJob(MyJob.class).storeDurably().build();
    }
    @Bean
    public Trigger trigger(JobDetail jobDetail) {
        return TriggerBuilder.newTrigger()
            .forJob(jobDetail)
            .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
            .build();
    }
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource ds, PlatformTransactionManager tm) {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setDataSource(ds);
        factory.setTransactionManager(tm);
        factory.setTriggers(trigger(jobDetail()));
        factory.setQuartzProperties(quartzProps());
        return factory;
    }
}

八、總結

Spring 整合 Quartz 核心思想:「大容器管小容器」。Spring 管理 Scheduler 生命周期,Quartz 專注調度邏輯。FactoryBean 模式讓業務代碼零依賴 Quartz API,遷移至 Spring Boot 只需將 XML 翻譯為 @Bean 方法。掌握 Cron 表達式、線程池、持久化集群三大進階點,即可應對企業級調度場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved