• Springcloud学习笔记43任务调度框架Quartz 使用02


    1.pom 依赖配置和生成数据库表

    1.1 pom 依赖配置

            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.3.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>5.3.16</version>
            </dependency>

    1.2 生成quartz相关的数据库表

    在数据库中添加quartz相关表

    共11张表,前6张都是关于各种triggers的信息,后面包括job,悲观锁,调度状态等信息;相关表操作在类StdJDBCDelegate中,相关sql语句在StdJDBCConstants中;

    (1) qrtz_blob_triggers

    自定义的triggers使用blob类型进行存储,非自定义的triggers不会存放在此表中,Quartz提供的triggers包括:CronTrigger,CalendarIntervalTrigger,

    DailyTimeIntervalTrigger以及SimpleTrigger,这几个trigger信息会保存在后面的几张表中;

    (2)qrtz_cron_triggers

    存储CronTrigger,这也是我们使用最多的触发器,在配置文件中做如下配置,即可在qrtz_cron_triggers生成记录:

    (3)qrtz_simple_triggers

    存储SimpleTrigger,在配置文件中做如下配置,即可在qrtz_simple_triggers生成记录:

    (4)qrtz_simprop_triggers

    存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种类型的触发器,使用CalendarIntervalTrigger做如下配置:

    CalendarIntervalTrigger没有对应的FactoryBean,直接设置实现类CalendarIntervalTriggerImpl;指定的重复周期是1,默认单位是天,也就是每天执行一次,查看表如下:提供了3个string类型的参数,2个int类型的参数,2个long类型的参数,2个decimal类型的参数以及2个boolean类型的参数;具体每个参数是什么含义,根据不同的trigger类型存放各自的参数;

    (5)qrtz_fired_triggers

    存储已经触发的trigger相关信息,trigger随着时间的推移状态发生变化,直到最后trigger执行完成,从表中被删除;已SimpleTrigger为例重复3次执行,查询表:

    (6)qrtz_triggers

    触发器的基本信息

    (7)qrtz_job_details

    存储jobDetails信息,相关信息在定义的时候指定,如上面定义的JobDetailFactoryBean,查询数据库:

    JOB_DATA存放的就是定义task时指定的jobDataMap属性,所以此属性需要实现Serializable接口,方便持久化到数据库;

    (8)qrtz_calendars

    Quartz为我们提供了日历的功能,可以自己定义一个时间段,可以控制触发器在这个时间段内触发或者不触发;现在提供6种类型:AnnualCalendar,CronCalendar,DailyCalendar,HolidayCalendar,MonthlyCalendar,WeeklyCalendar;

    (9)qrtz_paused_trigger_grps

    存放暂停掉的触发器,测试手动暂停firstCronTrigger

    (10)qrtz_scheduler_state

    存储所有节点的scheduler,会定期检查scheduler是否失效,启动多个scheduler,查询数据库:

    记录了最后最新的检查时间,在quartz.properties中设置了CHECKIN_INTERVAL为1000,也就是每秒检查一次;

    (11)qrtz_locks

    Quartz提供的锁表,为多个节点调度提供分布式锁,实现分布式调度,默认有2个锁:

    #
    # In your Quartz properties file, you'll need to set 
    # org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    #
    #
    # By: Ron Cordell - roncordell
    #  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
    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(200) NOT NULL,
    JOB_GROUP VARCHAR(200) 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(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) 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(200) 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(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) 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(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) 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(200) NOT NULL,
        TRIGGER_GROUP VARCHAR(200) 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(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) 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(200) 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(200) 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(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) 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(200) NULL,
    JOB_GROUP VARCHAR(200) 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(200) 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);
    commit; 

    2.注册Quartz 任务(Job) 工厂和注册调度工厂

    2.1 注册Quartz 任务(Job) 工厂

    package com.ttbank.flep.config;
    
    import org.quartz.spi.TriggerFiredBundle;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.scheduling.quartz.AdaptableJobFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * @Author lucky
     * @Date 2022/4/1 15:50
     * 注册Quartz 任务(Job) 工厂
     */
    @Component
    public class QuartzJobFactory extends AdaptableJobFactory {
        @Autowired
        private AutowireCapableBeanFactory capableBeanFactory; //AutowireCapableBeanFactory提供了自动装配Bean的实现,提供bean创建(带有构造函数解析)、属性填充、连接(包括自动装配)和初始化
    
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            //调用父类的方法
            Object jobInstance = super.createJobInstance(bundle);
            //进行注入
            capableBeanFactory.autowireBean(jobInstance);
            return jobInstance;
        }
    }

    2.2 配置数据库连接池

    (1)读取yaml文件中的配置项

    package com.ttbank.flep.config;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    /**
     * @Author lucky
     * @Date 2022/3/31 10:22
     */
    @Data
    @Component
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    public class DataSourceProperties {
        private String driverClassName;
        private String url;
        private String username;
        private String password;
        private int initialSize;
        private int minIdle;
        private int maxActive=100;
        private long maxWait;
        private long timeBetweenEvictionRunsMillis;
        private long minEvictableIdleTimeMillis;
        private String validationQuery;
        private boolean testWhileIdle;
        private boolean testOnBorrow;
        private boolean testOnReturn;
    
    }

    (2)配置数据库连接池,注入DataSource

    package com.ttbank.flep.config;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.sql.DataSource;
    import java.sql.SQLException;
    
    /**
     * @Author lucky
     * @Date 2022/4/1 9:18
     * 配置数据库连接池,注入DataSource
     */
    @Configuration
    public class DruidConfig {
        @Autowired
        private DataSourceProperties dataSourceProperties;
    
        @Bean
        public DataSource druidDataSource(){
            DruidDataSource druidDataSource=new DruidDataSource();
            druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
            druidDataSource.setUrl(dataSourceProperties.getUrl());
            druidDataSource.setUsername(dataSourceProperties.getUsername());
            druidDataSource.setPassword(dataSourceProperties.getPassword());
            druidDataSource.setInitialSize(dataSourceProperties.getInitialSize());
            druidDataSource.setMinIdle(dataSourceProperties.getMinIdle());
            druidDataSource.setMaxActive(dataSourceProperties.getMaxActive());
            druidDataSource.setMaxWait(dataSourceProperties.getMaxWait());
            druidDataSource.setTimeBetweenEvictionRunsMillis(dataSourceProperties.getTimeBetweenEvictionRunsMillis());
            druidDataSource.setMinEvictableIdleTimeMillis(dataSourceProperties.getMinEvictableIdleTimeMillis());
            druidDataSource.setValidationQuery(dataSourceProperties.getValidationQuery());
            druidDataSource.setTestWhileIdle(dataSourceProperties.isTestWhileIdle());
            druidDataSource.setTestOnBorrow(dataSourceProperties.isTestOnBorrow());
            druidDataSource.setTestOnReturn(dataSourceProperties.isTestOnReturn());
    
            try {
                druidDataSource.init();
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
            return druidDataSource;
        }
    
    }

    2.3 注册调度工厂

    package com.ttbank.flep.config;
    
    import org.quartz.Scheduler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.PropertiesFactoryBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.scheduling.quartz.LocalDataSourceJobStore;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    
    import javax.sql.DataSource;
    import java.io.IOException;
    
    /**
     * @Author lucky
     * @Date 2022/4/1 16:23
     * 注册调度工厂
     */
    @Configuration
    public class QuartzConfig {
        @Autowired
        private QuartzJobFactory jobFactory;
    
        @Autowired
        private DataSource dataSource;
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean() throws IOException{
            //01 获取配置属性
            PropertiesFactoryBean propertiesFactoryBean=new PropertiesFactoryBean();
            propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
            //在quartz.properties中的属性被读取并注入后再初始化对象;
            propertiesFactoryBean.afterPropertiesSet();
            //02 创建SchedulerFactoryBean
            SchedulerFactoryBean factory=new SchedulerFactoryBean();
            factory.setQuartzProperties(propertiesFactoryBean.getObject());
            factory.setJobFactory(jobFactory);
            factory.setApplicationContextSchedulerContextKey("applicationContextKey");
            //当spring关闭时,会等待所有已经启动的quartz job结束后才能完全shutdown
            factory.setWaitForJobsToCompleteOnShutdown(true);
            //是否覆盖已经存在的JOB
            factory.setOverwriteExistingJobs(false);
            factory.setStartupDelay(10);
            factory.setDataSource(dataSource);
            return factory;
    
    
        }
    
        @Bean(name="scheduler")
        public Scheduler scheduler() throws IOException{
            Scheduler scheduler = schedulerFactoryBean().getScheduler();
            return scheduler;
        }
    
    }

    3.controller

    package com.ttbank.flep.controller;
    
    import com.ttbank.flep.service.QuartzService;
    import dto.AppQuartzDTO;
    import dto.Result;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    /**
     * @Author lucky
     * @Date 2022/4/1 17:50
     */
    @RestController
    @RequestMapping("/quartztest")
    public class QuartzController {
        @Autowired
        QuartzService quartzService;
    
        /**
         * 添加任务
         */
        @PostMapping("/addJob")
        public Result addJob(@RequestBody AppQuartzDTO appQuartzDTO){
            quartzService.addJob(appQuartzDTO);
            return Result.success();
        }
    
        /**
         * 暂停任务
         */
        @PostMapping("/pauseJob")
        public Result pauseJob(@RequestParam String jobName,@RequestParam String jobGroupName){
            quartzService.pauseJob(jobName,jobGroupName);
            return Result.success();
        }
    
        /**
         * 恢复任务
         */
        @PostMapping("/resumeJob")
        public Result resumeJob(@RequestParam String jobName,@RequestParam String jobGroupName){
            quartzService.resumeJob(jobName,jobGroupName);
            return Result.success();
        }
    
        /**
         * 添加任务
         */
        @PostMapping("/modifyJob")
        public void modifyJob(@RequestBody AppQuartzDTO appQuartzDTO){
            quartzService.modifyJob(appQuartzDTO);
        }
    
    
    
    }

    4.Service

    (1)QuartzService接口

    package com.ttbank.flep.service;
    
    import dto.AppQuartzDTO;
    
    /**
     * @Author lucky
     * @Date 2022/4/2 11:49
     */
    public interface QuartzService {
        /**
         * 新建任务
         * @param appQuartzDTO
         */
        void addJob(AppQuartzDTO appQuartzDTO);
    
        /**
         * 暂停任务
         * @param jobName
         * @param jobGroupName
         */
        void pauseJob(String jobName,String jobGroupName);
    
        /**
         * 恢复任务
         * @param jobName
         * @param jobGroupName
         */
        void resumeJob(String jobName, String jobGroupName);
    
        /**
         * 修改任务
         * @param appQuartzDTO
         */
        void modifyJob(AppQuartzDTO appQuartzDTO);
    }

    (2) QuartzServiceImpl

    package com.ttbank.flep.service.impl;
    
    import com.ttbank.flep.constant.QuartzJobDataKey;
    import com.ttbank.flep.job.BaseJob;
    import com.ttbank.flep.service.QuartzService;
    import dto.AppQuartzDTO;
    import lombok.extern.slf4j.Slf4j;
    import org.quartz.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.PostConstruct;
    
    /**
     * @Author lucky
     * @Date 2022/4/2 15:34
     */
    @Slf4j
    @Service
    public class QuartzServiceImpl implements QuartzService {
        @Autowired
        @Qualifier("scheduler")
        private Scheduler scheduler;
    
        @PostConstruct
        public void startScheduler(){
            try {
                scheduler.start();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
    
        @Override
        public void addJob(AppQuartzDTO appQuartzDTO) {
            try {
                //01 构建job信息;
                JobDetail jobDetail = JobBuilder.newJob(getClass(appQuartzDTO.getClassName().trim()).getClass())
                        .withIdentity(appQuartzDTO.getJobName(), appQuartzDTO.getJobGroup())
                        .build();
                //02 表达式调度构建器(任务执行的时间)
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartzDTO.getCronExpression());
                //03 按新的CronExpression表达式构建一个新的trigger
                CronTrigger trigger = TriggerBuilder.newTrigger()
                        .withIdentity(appQuartzDTO.getJobName(), appQuartzDTO.getJobGroup())
                        .withSchedule(cronScheduleBuilder)
                        .build();
                //04 获得JobDataMap,写入数据
                fillJobDataMap(trigger.getJobDataMap(),appQuartzDTO );
                scheduler.scheduleJob(jobDetail,trigger);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void pauseJob(String jobName, String jobGroupName) {
            try {
                scheduler.pauseJob(JobKey.jobKey(jobName,jobGroupName));
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void resumeJob(String jobName, String jobGroupName) {
            try {
                scheduler.resumeJob(JobKey.jobKey(jobName,jobGroupName));
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void modifyJob(AppQuartzDTO appQuartzDTO) {
            try {
                //01 根据任务名和任务组获取触发器Trigger
                TriggerKey triggerKey = TriggerKey.triggerKey(appQuartzDTO.getJobName(), appQuartzDTO.getJobGroup());
                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                //02 表达式调度构建器
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartzDTO.getCronExpression());
                //03 按照新的CronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder()
                        .withIdentity(triggerKey)
                        .withSchedule(cronScheduleBuilder)
                        .build();
                //04 获得JobDataMap,写入数据
                fillJobDataMap(trigger.getJobDataMap(),appQuartzDTO );
                //05 按照新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey,trigger );
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        private void fillJobDataMap(JobDataMap jobDataMap,AppQuartzDTO appQuartzDTO){
            jobDataMap.put(QuartzJobDataKey.CLASS_NAME,appQuartzDTO.getClassName() );
            jobDataMap.put(QuartzJobDataKey.METHOD_NAME,appQuartzDTO.getMethodName() );
            jobDataMap.put(QuartzJobDataKey.PARAMS,appQuartzDTO.getParams() );
            jobDataMap.put(QuartzJobDataKey.CRON_EXPRESS,appQuartzDTO.getCronExpression() );
        }
    
        /**
         * 根据类名称,通过反射得到该类;
         * @param classname
         * @throws Exception
         */
        private static BaseJob getClass(String classname) throws Exception {
            Class<?> class1 = Class.forName(classname);
            return (BaseJob) class1.newInstance();
        }
    
    
    }

    5. Job 任务

    (1)BaseJob

    package com.ttbank.flep.job;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    /**
     * @Author lucky
     * @Date 2022/4/6 9:27
     */
    public interface BaseJob extends Job {
        /**
         * 任务具体执行方法
         * @param jobExecutionContext
         * @throws JobExecutionException
         */
        @Override
        void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException;
    }

    (2)ExecSdkJob

    package com.ttbank.flep.job;
    
    import com.sun.media.jfxmedia.logging.Logger;
    import com.ttbank.flep.constant.QuartzJobDataKey;
    import lombok.extern.slf4j.Slf4j;
    import org.quartz.*;
    
    import java.io.*;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    /**
     * @Author lucky
     * @Date 2022/4/6 10:12
     */
    @Slf4j
    @PersistJobDataAfterExecution
    @DisallowConcurrentExecution
    public class ExecSdkJob implements BaseJob {
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            try {
                JobDataMap jobDataMap = context.getTrigger().getJobDataMap();
                String params = jobDataMap.getString(QuartzJobDataKey.PARAMS);
    
                log.info(params);
                FileOutputStream fileOutputStream=new FileOutputStream("D:\\data\\quartz_test01.txt",true);
                LocalDateTime localDateTime=LocalDateTime.now();
                String currentTime = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh-mm-ss"));
                fileOutputStream.write(("当前时间为:"+currentTime+"\n").getBytes());
                fileOutputStream.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    【转载】实体框架之领域驱动实践(七):模型对象的生命周期 仓储
    【转载】实体框架之领域驱动实践(四):存储过程 领域驱动的反模式
    【转载】实体框架之领域驱动实践(五):聚合
    VC6.0下配置boost库使用正则表达式(解决问题)
    boost regexpre 用于MFC时出现 'boost' : is not a class or namespace name错误
    VC技巧:在程序的状态栏中实现进度条
    正则表达式 boost regexp的安装
    最近在做实验希望实现基于JNI技术在Java中使用 Slex.dll
    利用BCGControlBar 实现状态条显示Progressbar
    正则表达式30分钟入门教程
  • 原文地址:https://www.cnblogs.com/luckyplj/p/16111584.html
Copyright © 2020-2023  润新知