美文网首页Spring技巧
springboot集成quartz, 使用xml配置任务

springboot集成quartz, 使用xml配置任务

作者: 饱饱想要灵感 | 来源:发表于2023-10-15 14:01 被阅读0次

    首先添加依赖

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

    1. 新建定时器任务配置类

    import com.o2.moms.qrtz.MonitorJobListener;
    import com.o2.moms.qrtz.MonitorTriggerListener;
    import org.quartz.JobListener;
    import org.quartz.TriggerListener;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.transaction.PlatformTransactionManager;
    
    import javax.sql.DataSource;
    import java.util.concurrent.Executor;
    
    @Configuration
    @EnableScheduling
    @ConditionalOnProperty(name= "init.quartz", havingValue = "true")
    public class JobConfig implements SchedulerFactoryBeanCustomizer {
        @Autowired
        private DataSource dataSource;
        @Autowired
        private PlatformTransactionManager transactionManager;
        @Override
        public void customize(SchedulerFactoryBean schedulerFactoryBean) {
            schedulerFactoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
            schedulerFactoryBean.setTaskExecutor(executor());
            schedulerFactoryBean.setDataSource(dataSource);
            schedulerFactoryBean.setTransactionManager(transactionManager);
            schedulerFactoryBean.setStartupDelay(30);
            schedulerFactoryBean.setGlobalTriggerListeners(monitorTriggerListener());
            schedulerFactoryBean.setGlobalJobListeners(monitorJobListener());
            schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
        }
    
        @Bean
        public TriggerListener monitorTriggerListener() {
            TriggerListener triggerListener = new MonitorTriggerListener();
            return triggerListener;
        }
    
        @Bean
        public JobListener monitorJobListener() {
            JobListener jobListener = new MonitorJobListener();
            return jobListener;
        }
    
        @Bean
        public Executor executor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(20);
            executor.setQueueCapacity(20);
            return executor;
        }
    //    @Bean(destroyMethod = "destroy")
    //    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource,PlatformTransactionManager transactionManager) {
    //        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
    //        schedulerFactoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
    //        schedulerFactoryBean.setTaskExecutor(executor());
    //        schedulerFactoryBean.setDataSource(dataSource);
    //        schedulerFactoryBean.setTransactionManager(transactionManager);
    //        schedulerFactoryBean.setStartupDelay(30);
    //        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
    //        return schedulerFactoryBean;
    //    }
    
    }
    

    2. 添加quartz.properties配置文件

    #============================================================================
    # Configure Main Scheduler Properties
    #============================================================================
    org.quartz.scheduler.instanceName: quartzScheduler
    org.quartz.scheduler.instanceId: AUTO
    org.quartz.scheduler.skipUpdateCheck: true
    org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.CascadingClassLoadHelper
    
    #============================================================================
    # Configure JobStore  
    #============================================================================
    org.quartz.jobStore.isClustered=true
    org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
    #org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore
    
    org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
    org.quartz.jobStore.tablePrefix=QRTZ_
    org.quartz.jobStore.misfireThreshold=60000
    org.quartz.jobStore.useProperties=false
    
    org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
    org.quartz.plugin.jobInitializer.fileNames=quartz_jobs.xml
    org.quartz.plugin.jobInitializer.failOnFileNotFound = true
    org.quartz.plugin.jobInitializer.scanInterval = 0
    org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
    
    org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
    org.quartz.plugin.shutdownhook.cleanShutdown = true
    org.quartz.jobStore.acquireTriggersWithinLock = true
    

    application.properties添加参数

    init.quartz=true
    

    3. quartz_jobs.xml配置

    服务启动时所有任务都会初始化为等待状态, 关于定时器状态可以参考这篇博客Quartz 触发器状态与生命周期

    <?xml version="1.0" encoding="UTF-8"?>
    <job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
        version="1.8">
        
        <pre-processing-commands>
            <delete-jobs-in-group>*</delete-jobs-in-group>  <!-- 清除调度器中的所有作业 -->
            <delete-triggers-in-group>*</delete-triggers-in-group> <!-- 清除调度器中的所有触发器 -->
        </pre-processing-commands>
        
        <processing-directives>
            <!-- 如果调度程序中有任何同名的作业/触发器(与此文件中相同),会覆盖它们 -->
            <overwrite-existing-data>true</overwrite-existing-data>
            <!-- 如果调度程序中有任何同名的作业/触发器(与此文件中相同),并且覆盖为false,则忽略它们,而不是生成错误 -->
            <ignore-duplicates>false</ignore-duplicates> 
        </processing-directives>
        
        <schedule>
            <job>
                <name>TestJob1</name>
                <job-class>org.quartz.examples.example10.SimpleJob</job-class>
            </job>
            
            <job>
                <name>TestDurableJob</name>
                <job-class>org.quartz.examples.example10.SimpleJob</job-class>
                <durability>true</durability>
                <recover>false</recover>
            </job>
            
            <trigger>
                <simple>
                    <name>TestSimpleTrigger1AtFiveSecondInterval</name>
                    <job-name>TestJob1</job-name>
                    <repeat-count>-1</repeat-count> <!-- repeat indefinitely  -->
                    <repeat-interval>5000</repeat-interval>  <!--  every 5 seconds -->
                </simple>
            </trigger>
        
            <job>
                <name>TestJob2</name>
                <group>GroupOfTestJob2</group>
                <description>This is the description of TestJob2</description>
                <job-class>org.quartz.examples.example10.SimpleJob</job-class>
                <durability>false</durability>
                <recover>true</recover>
                <job-data-map>
                    <entry>
                        <key>someKey</key>
                        <value>someValue</value>
                    </entry>
                    <entry>
                        <key>someOtherKey</key>
                        <value>someOtherValue</value>
                    </entry>
                </job-data-map>
            </job>
            
            <trigger>
                <simple>
                    <name>TestSimpleTrigger2AtTenSecondIntervalAndFiveRepeats</name>
                    <group>GroupOfTestJob2Triggers</group>
                    <job-name>TestJob2</job-name>
                    <job-group>GroupOfTestJob2</job-group>
                    <start-time>2010-02-09T10:15:00</start-time>
                    <misfire-instruction>MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT</misfire-instruction>
                    <repeat-count>5</repeat-count>
                    <repeat-interval>10000</repeat-interval>
                </simple>
            </trigger>
            
            <trigger>
                <cron>
                    <name>TestCronTrigger2AtEveryMinute</name>
                    <group>GroupOfTestJob2Triggers</group>
                    <job-name>TestJob2</job-name>
                    <job-group>GroupOfTestJob2</job-group>
                    <job-data-map>
                        <entry>
                            <key>someKey</key>
                            <value>overriddenValue</value>
                        </entry>
                        <entry>
                            <key>someOtherKey</key>
                            <value>someOtherOverriddenValue</value>
                        </entry>
                    </job-data-map>
                    <cron-expression>0 * * ? * *</cron-expression>
                </cron>
            </trigger>
        
            <trigger>
                <cron>
                    <name>TestCronTrigger2AtEveryMinuteOnThe45thSecond</name>
                    <group>GroupOfTestJob2Triggers</group>
                    <job-name>TestJob2</job-name>
                    <job-group>GroupOfTestJob2</job-group>
                    <start-time>2010-02-09T12:26:00.0</start-time>
                    <end-time>2012-02-09T12:26:00.0</end-time>
                    <misfire-instruction>MISFIRE_INSTRUCTION_SMART_POLICY</misfire-instruction>
                    <cron-expression>45 * * ? * *</cron-expression>
                    <time-zone>America/Los_Angeles</time-zone>
                </cron>
            </trigger>
        </schedule>    
    </job-scheduling-data>
    

    4. 任务类,xml配置文件里指向的job任务类

    package org.quartz.examples.example10;
    
    import java.util.Date;
    import java.util.Set;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.JobKey;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * job任务类
     */
    public class SimpleJob implements Job {
    
        private static Logger LOG = LoggerFactory.getLogger(SimpleJob.class);
    
        // 必须要有public修饰的无参构造函数
        public SimpleJob() {
        }
    
        // 定时器执行方法
        @SuppressWarnings("unchecked")
        public void execute(JobExecutionContext context) throws JobExecutionException {
            JobKey jobKey = context.getJobDetail().getKey();
            LOG.info("--------- job任务执行: " + jobKey + " executing at " + new Date() + ", fired by: "
                    + context.getTrigger().getKey());
    
            if (context.getMergedJobDataMap().size() > 0) {
                Set<String> keys = context.getMergedJobDataMap().keySet();
                for (String key : keys) {
                    String val = context.getMergedJobDataMap().getString(key);
                    LOG.info("--------- job任务执行。 - jobDataMap entry: " + key + " = " + val);
                }
            }
    
            context.setResult("hello");
        }
    
    }
    

    附: 数据库初始化语句

    DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
    DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
    DROP TABLE IF EXISTS QRTZ_LOCKS;
    DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
    DROP TABLE IF EXISTS QRTZ_CALENDARS;
     
    CREATE TABLE QRTZ_JOB_DETAILS(
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME VARCHAR(190) NOT NULL,
    JOB_GROUP VARCHAR(190) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    JOB_NAME VARCHAR(190) NOT NULL,
    JOB_GROUP VARCHAR(190) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(190) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
    REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_CRON_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    CRON_EXPRESSION VARCHAR(120) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_SIMPROP_TRIGGERS
      (
        SCHED_NAME VARCHAR(120) NOT NULL,
        TRIGGER_NAME VARCHAR(190) NOT NULL,
        TRIGGER_GROUP VARCHAR(190) NOT NULL,
        STR_PROP_1 VARCHAR(512) NULL,
        STR_PROP_2 VARCHAR(512) NULL,
        STR_PROP_3 VARCHAR(512) NULL,
        INT_PROP_1 INT NULL,
        INT_PROP_2 INT NULL,
        LONG_PROP_1 BIGINT NULL,
        LONG_PROP_2 BIGINT NULL,
        DEC_PROP_1 NUMERIC(13,4) NULL,
        DEC_PROP_2 NUMERIC(13,4) NULL,
        BOOL_PROP_1 VARCHAR(1) NULL,
        BOOL_PROP_2 VARCHAR(1) NULL,
        PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_BLOB_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_CALENDARS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME VARCHAR(190) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_FIRED_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    INSTANCE_NAME VARCHAR(190) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(190) NULL,
    JOB_GROUP VARCHAR(190) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_SCHEDULER_STATE (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(190) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
    ENGINE=InnoDB;
     
    CREATE TABLE QRTZ_LOCKS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME VARCHAR(40) NOT NULL,
    PRIMARY KEY (SCHED_NAME,LOCK_NAME))
    ENGINE=InnoDB;
     
    -- CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
    -- CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
     
    -- CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
    -- CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
    -- CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
    -- CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
    -- CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
    -- CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
    -- CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
    -- CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
    -- CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
    -- CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
    -- CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
    -- CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
     
    -- CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
    -- CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
    -- CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
    -- CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
    -- CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
    -- CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
    

    相关文章

      网友评论

        本文标题:springboot集成quartz, 使用xml配置任务

        本文链接:https://www.haomeiwen.com/subject/cyfnbdtx.html