springboot Quartz集成-分布式版和示例

說明

分布式動態(tài)定時任務(wù)場景耸序。

具體配置

1.需要引入的maven依賴

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <quartz.version>2.2.3</quartz.version>
    </properties>

        <!--quartz相關(guān)依賴-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>${quartz.version}</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>${quartz.version}</version>
        </dependency>

2. 采用bean的方式注冊配置

@Configuration
@EnableScheduling
public class QuartzConfiguration {
    /**
     * 繼承org.springframework.scheduling.quartz.SpringBeanJobFactory
     * 實現(xiàn)任務(wù)實例化方式
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
            ApplicationContextAware {

        private transient AutowireCapableBeanFactory beanFactory;

        @Override
        public void setApplicationContext(final ApplicationContext context) {
            beanFactory = context.getAutowireCapableBeanFactory();
        }

        /**
         * 將job實例交給spring ioc托管
         * 我們在job實例實現(xiàn)類內(nèi)可以直接使用spring注入的調(diào)用被spring ioc管理的實例
         * @param bundle
         * @return
         * @throws Exception
         */
        @Override
        protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
            final Object job = super.createJobInstance(bundle);
            /**
             * 將job實例交付給spring ioc
             */
            beanFactory.autowireBean(job);
            return job;
        }
    }

    /**
     * 配置任務(wù)工廠實例
     * @param applicationContext spring上下文實例
     * @return
     */
    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext)
    {
        /**
         * 采用自定義任務(wù)工廠 整合spring實例來完成構(gòu)建任務(wù)
         * see {@link AutowiringSpringBeanJobFactory}
         */
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    /**
     * 配置任務(wù)調(diào)度器
     * 使用項目數(shù)據(jù)源作為quartz數(shù)據(jù)源
     * @param jobFactory 自定義配置任務(wù)工廠
     * @param dataSource 數(shù)據(jù)源實例
     * @return
     * @throws Exception
     */
    @Bean(destroyMethod = "destroy",autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception
    {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        //將spring管理job自定義工廠交由調(diào)度器維護
        schedulerFactoryBean.setJobFactory(jobFactory);
        //設(shè)置覆蓋已存在的任務(wù)
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        //項目啟動完成后,等待2秒后開始執(zhí)行調(diào)度器初始化
        schedulerFactoryBean.setStartupDelay(2);
        //設(shè)置調(diào)度器自動運行
        schedulerFactoryBean.setAutoStartup(true);
        //設(shè)置數(shù)據(jù)源鲁猩,使用與項目統(tǒng)一數(shù)據(jù)源
        schedulerFactoryBean.setDataSource(dataSource);
        //設(shè)置上下文spring bean name
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
        //設(shè)置配置文件位置
        schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
        return schedulerFactoryBean;
    }

}

3.需要加載的 quartz.properties

將隨時需要修改的一些配置提取到 quartz.properties中坎怪,文件文件可放入外部,也可以放入../src/main/resources下廓握,quartz.properties的具體的配置和解釋:

#調(diào)度器實例名稱
org.quartz.scheduler.instanceName = quartzScheduler

#調(diào)度器實例編號自動生成
org.quartz.scheduler.instanceId = AUTO

#持久化方式配置
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

#持久化方式配置數(shù)據(jù)驅(qū)動搅窿,MySQL數(shù)據(jù)庫
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

#quartz相關(guān)數(shù)據(jù)表前綴名
org.quartz.jobStore.tablePrefix = QRTZ_

#開啟分布式部署
org.quartz.jobStore.isClustered = true
#配置是否使用
org.quartz.jobStore.useProperties = false

#分布式節(jié)點有效性檢查時間間隔,單位:毫秒
org.quartz.jobStore.clusterCheckinInterval = 20000

#線程池實現(xiàn)類
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

#執(zhí)行最大并發(fā)線程數(shù)量
org.quartz.threadPool.threadCount = 10

#線程優(yōu)先級
org.quartz.threadPool.threadPriority = 6

#配置為守護線程隙券,設(shè)置后任務(wù)將不會執(zhí)行
#org.quartz.threadPool.makeThreadsDaemons=true

#配置是否啟動自動加載數(shù)據(jù)庫內(nèi)的定時任務(wù)男应,默認true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

4.需要執(zhí)行的quartz sql腳本內(nèi)容

因為使用的是工程的數(shù)據(jù)源,將以下表加入工程數(shù)據(jù)庫中即可是尔。

use `your_db`;

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; 

5. Quartz常用操作工具類

@Component
@Slf4j
public class QuartzManager {


    /**
     * 注入任務(wù)調(diào)度器
     */
    @Autowired
    private Scheduler scheduler;


    /**
     * @Description: 添加一個定時任務(wù)
     *
     * @param name 任務(wù)名
     * @param groupName  任務(wù)組名
     * @param jobClass  任務(wù)
     * @param cron  時間設(shè)置殉了,參考quartz說明文檔
     * @param paramMap   任務(wù)執(zhí)行所需的參數(shù)
     */
    public void addJob(String name, String groupName, Class jobClass, String cron, Map<String, Object> paramMap) {
        try {
//            Scheduler sched = schedulerFactory.getScheduler();
            // 任務(wù)名,任務(wù)組拟枚,任務(wù)執(zhí)行類
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(name, groupName).build();

            // 觸發(fā)器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 觸發(fā)器名,觸發(fā)器組
            triggerBuilder.withIdentity(name, groupName);
//            triggerBuilder.withPriority(1);
            triggerBuilder.startNow();
            // 觸發(fā)器時間設(shè)定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 創(chuàng)建Trigger對象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();

            // 業(yè)務(wù)邏輯參數(shù)傳遞
            if (paramMap.get(Constant.CHANNEL) != null) {
                if (jobDetail.getJobDataMap().get(Constant.CHANNEL) != null) {
                    log.info("=======channelJson = " + jobDetail.getJobDataMap().get(Constant.CHANNEL));
                }
                Object channel = paramMap.get(Constant.CHANNEL);
                String channelJson = JSONObject.toJSONString(channel);
                jobDetail.getJobDataMap().put(Constant.CHANNEL, channelJson);
            }
            if (paramMap.get(Constant.PROGRAM) != null) {
                Program program = (Program) paramMap.get(Constant.PROGRAM);
                String programJson = JSONObject.toJSONString(program);
                jobDetail.getJobDataMap().put(Constant.PROGRAM, programJson);
            }

            // 調(diào)度容器設(shè)置JobDetail和Trigger
            scheduler.scheduleJob(jobDetail, trigger);

            // 啟動
            if (!scheduler.isShutdown()) {
                scheduler.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }


    /**
     * @Description: 修改一個任務(wù)的觸發(fā)時間
     *
     * @param name
     * @param groupName
     * @param cron   時間設(shè)置薪铜,參考quartz說明文檔
     */
    public void modifyJobTime(String name, String groupName, String cron) {
        try {

            TriggerKey triggerKey = TriggerKey.triggerKey(name, groupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }


            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(cron)) {
                /** 方式一 :調(diào)用 rescheduleJob 開始 */
                // 觸發(fā)器
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 觸發(fā)器名,觸發(fā)器組
                triggerBuilder.withIdentity(name, groupName);
                triggerBuilder.startNow();
                // 觸發(fā)器時間設(shè)定
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 創(chuàng)建Trigger對象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一個任務(wù)的觸發(fā)時間
                scheduler.rescheduleJob(triggerKey, trigger);
                /** 方式一 :調(diào)用 rescheduleJob 結(jié)束 */


                /** 方式二:先刪除众弓,然后在創(chuàng)建一個新的Job  */
                //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
                //Class<? extends Job> jobClass = jobDetail.getJobClass();
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
                /** 方式二 :先刪除,然后在創(chuàng)建一個新的Job */
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description: 移除一個任務(wù)
     *
     * @param name
     * @param groupName
     */
    public void removeJob(String name, String groupName) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(name, groupName);
            scheduler.pauseTrigger(triggerKey);// 停止觸發(fā)器
            scheduler.unscheduleJob(triggerKey);// 移除觸發(fā)器
            scheduler.deleteJob(JobKey.jobKey(name, groupName));// 刪除任務(wù)
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description:啟動所有定時任務(wù)
     */
    public void startJobs() {
        try {

            scheduler.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description:關(guān)閉所有定時任務(wù)
     */
    public void shutdownJobs() {
        try {

            if (!scheduler.isShutdown()) {
                scheduler.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static String formatDateByPattern(Date date, String dateFormat){
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String formatTimeStr = null;
        if (date != null) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }

    public static String getCron(Date date){
        String dateFormat="ss mm HH dd MM ? yyyy";
        return formatDateByPattern(date, dateFormat);
    }
}

6.使用示例 - 添加Job

場景模擬:指定某個用戶在某個時間進行什么工作隔箍。
實例代碼:DemoAddQuartzJob.java

@Service
public class DemoAddQuartzJob {

    @Autowired
    private QuartzManager quartzManager;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void addJob(){

        String jobGroupName = "定時監(jiān)看";
        String jobName = UUID.randomUUID().toString();

        // 設(shè)置要傳入實現(xiàn)job的具體參數(shù)對象
        Map<String, Object> paramMap = new HashMap<>();

        // 定義work主體
        Map<String,String> work = new HashMap<>();
        work.put("eat","eating");
        work.put("drink","drinking");
        work.put("play","playing");
        work.put("happy","happying");

        paramMap.put("userName", "BeeHoney");
        paramMap.put("work", work);


        // 設(shè)置定時的時間
        Date startTime = new Date();
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
        calendar.setTime(startTime);
        // 一個小時后執(zhí)行
        calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 1);
        // 最終的時間
        System.out.println("設(shè)置的定時時間為:"+sdf.format(calendar.getTime()));
        startTime = calendar.getTime();


        // 執(zhí)行時間
        String corn = TimeUtils.getCron(startTime);

        // 設(shè)置開始切換節(jié)目的定時任務(wù)谓娃,到指定時間執(zhí)行 DemoAddQuartzJob.class為具體要做的事情的實現(xiàn),下一個示例給出蜒滩。
        quartzManager.addJob(jobName, jobGroupName, DemoAddQuartzJob.class, corn, paramMap);
    }

    static class TimeUtils {
        public static String formatDateByPattern(Date date, String dateFormat){
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
            String formatTimeStr = null;
            if (date != null) {
                formatTimeStr = sdf.format(date);
            }
            return formatTimeStr;
        }

        public static String getCron(Date date){
            String dateFormat="ss mm HH dd MM ? yyyy";
            return formatDateByPattern(date, dateFormat);
        }
    }
}

7.使用示例 - 實現(xiàn)Job

場景模擬:指定某個用戶在某個時間進行什么工作的具體實現(xiàn)滨达。
說明: 此方法類是一個通用的實現(xiàn),描述了所有用戶觸發(fā)定時任務(wù)后都會去做同一類事情(DemoQuartzJob)俯艰,如果做不同的事情捡遍,那就 新創(chuàng)建一個implements Job 的方法類,如DemoQuartzJob2 DemoQuartzJob3 ... 竹握,如下通用示例:

DemoQuartzJob.java

@Component
public class DemoQuartzJob implements Job {

    /**
    *  實現(xiàn)定時任務(wù)具體要處理的邏輯
    * @param
    * @return
    */
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        // 解析創(chuàng)建該定時任務(wù)時設(shè)置的數(shù)據(jù)
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();

        String userName = (String) dataMap.get("userName");
        Map work = (Map) dataMap.get("work");

        // 輸出 該用戶在這個時刻要做的事情
        System.out.println(""+userName+" is work:"+work);

       // todo 要做的事情的具體實現(xiàn)
        
    }
}

更多画株,請關(guān)注:
springboot 技術(shù)實踐總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市啦辐,隨后出現(xiàn)的幾起案子谓传,更是在濱河造成了極大的恐慌,老刑警劉巖芹关,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件续挟,死亡現(xiàn)場離奇詭異,居然都是意外死亡侥衬,警方通過查閱死者的電腦和手機诗祸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浇冰,“玉大人贬媒,你說我怎么就攤上這事≈庀埃” “怎么了际乘?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漂佩。 經(jīng)常有香客問我脖含,道長,這世上最難降的妖魔是什么投蝉? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任养葵,我火速辦了婚禮,結(jié)果婚禮上瘩缆,老公的妹妹穿的比我還像新娘关拒。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布着绊。 她就那樣靜靜地躺著谐算,像睡著了一般。 火紅的嫁衣襯著肌膚如雪归露。 梳的紋絲不亂的頭發(fā)上洲脂,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音剧包,去河邊找鬼恐锦。 笑死,一個胖子當(dāng)著我的面吹牛疆液,可吹牛的內(nèi)容都是我干的一铅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼堕油,長吁一口氣:“原來是場噩夢啊……” “哼馅闽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起馍迄,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎局骤,沒想到半個月后攀圈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡峦甩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年赘来,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凯傲。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡犬辰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冰单,到底是詐尸還是另有隱情幌缝,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布诫欠,位于F島的核電站涵卵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荒叼。R本人自食惡果不足惜轿偎,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望被廓。 院中可真熱鬧坏晦,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挖诸,卻和暖如春汁尺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背多律。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工痴突, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狼荞。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓辽装,卻偏偏與公主長得像,于是被迫代替她去往敵國和親相味。 傳聞我的和親對象是個殘疾皇子拾积,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容