任务调度管理器Quartz漫谈

1 篇文章 0 订阅
1 篇文章 0 订阅

quartz中主要有Job、JobDetail、Scheduler构成

在你需要执行的任务中只要实现Job类,然后在execute中执行具体的任务即可。你定义了一个实现Job接口的类,这个类仅仅表明该job需要完成什么类型的任务.

首先,我们可以实现一个定时任务管理类ScheduleManager.java:

package com.realtech.model;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;

/**
 * 定时任务管理类
 * @author yuanxiaozhong
 * 
 */
public class ScheduleManager {

    /**
     * 任务工厂类
     */
    private  Scheduler scheduler;


    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    /**
     * @Describe 添加一个任务
     * @param jobName 工作名称
     * @param groupName 组名称
     * @param cls 任务类名称
     * @param cronExpress 任务表达式
     */
    public void addJob(String jobName, String groupName, Class cls, String cronExpress){
        JobDetail jobDetail = JobBuilder.newJob(cls)
                .withIdentity(jobName, groupName)
                .build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpress);
        try {
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName)
                    .withSchedule(scheduleBuilder)
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 修改一个任务的出发时间,使用默认的任务名称,任务组
     * @param jobName 工作名称
     * @param groupName 组名称
     * @param cronExpress 任务表达式
     */
    public void modifyJob(String jobName, String groupName, String cronExpress){
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, groupName);
        try {
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            String oldExpress = trigger.getCronExpression();
            if (!oldExpress.equalsIgnoreCase(cronExpress)) {
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpress);
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                        .withSchedule(scheduleBuilder)
                        .build();
                scheduler.rescheduleJob(triggerKey, trigger);
            }
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 暂停一个任务
     * @param jobName
     * @param groupName
     */
    public void pauseJob(String jobName, String groupName){
        JobKey jobKey = JobKey.jobKey(jobName, groupName);
        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 恢复一个任务
     * @param jobName
     * @param groupName
     */
    public void resumeJob(String jobName, String groupName){
        JobKey jobKey = JobKey.jobKey(jobName, groupName);
        try {
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除任务
     * @param jobName
     * @param groupName
     */
    public void deleteJob(String jobName, String groupName){
        JobKey jobKey = JobKey.jobKey(jobName, groupName);
        try {
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 启动所有任务
     */
    public void startAll(){
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

如果你使用maven管理项目需要在src/main/resources下定义一个quartz.properties 文件,内容如下:

org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

让我们看看如何添加一个任务以及具体的执行流程

        /**
     * @Describe 添加一个任务
     * @param jobName 工作名称
     * @param groupName 组名称
     * @param cls 任务类名称
     * @param cronExpress 任务表达式
     */
    public void addJob(String jobName, String groupName, Class cls, String cronExpress){
        JobDetail jobDetail = JobBuilder.newJob(cls)
                .withIdentity(jobName, groupName)
                .build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpress);
        try {
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName)
                    .withSchedule(scheduleBuilder)
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

首先通过JobDetail创建一个对应的job实现类对象,并且指定任务名称和任务组,然后定义这个任务的执行时间周期,quartz提供了SimpleTrigger和 CronTriggers两种,前者执行一些简单的任务归类比如:

  CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔,复发的发射工作的时间表。

CronTrigger,你可以指定触发的时间表如“每星期五中午”,或“每个工作日9:30时”,甚至“每5分钟一班9:00和10:00逢星期一上午,星期三星期五“。
即便如此,SimpleTrigger一样,CronTrigger拥有的startTime指定的时间表时生效,指定的时间表时,应停止(可选)结束时间。

cron的表达式被用来配置CronTrigger实例。 cron的表达式是字符串,实际上是由七子表达式,描述个别细节的时间表。这些子表达式是分开的空白,代表:

1.        Seconds
2.        Minutes
3.        Hours
4.        Day-of-Month
5.        Month
6.        Day-of-Week
7.        Year (可选字段)
例  "0 0 12 ? * WED" 在每星期三下午12:00 执行,

个别子表达式可以包含范围, 例如,在前面的例子里(“WED”)可以替换成 “MON-FRI”, “MON, WED, FRI”甚至”MON-WED,SAT”.
“*” 代表整个时间段.

每一个字段都有一套可以指定有效值,如

Seconds (秒) :可以用数字0-59 表示,

Minutes(分) :可以用数字0-59 表示,

Hours(时) :可以用数字0-23表示,

Day-of-Month(天) :可以用数字1-31 中的任一一个值,但要注意一些特别的月份

Month(月) :可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示

Day-of-Week(每周):可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示

“/”:为特别单位,表示为“每”如“0/15”表示每隔15分钟执行一次,“0”表示为从“0”分开始, “3/20”表示表示每隔20分钟执行一次,“3”表示从第3分钟开始执行

“?”:表示每月的某一天,或第周的某一天

“L”:用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如“6L”表示“每月的最后一个星期五”

“W”:表示为最近工作日,如“15W”放在每月(day-of-month)字段上表示为“到本月15日最近的工作日”

““#”:是用来指定“的”每月第n个工作日,例 在每周(day-of-week)这个字段中内容为”6#3” or “FRI#3” 则表示“每月第三个星期五”

接下来就是如何定义个类并且实现Job中的execute方法,如定义一个RefreshTokenJob.java代码如下:

package com.realtech.model;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;

import com.realtech.consumer.RefreshTokenConsumer;

/**
 * 定时刷新access_token
 * @author yuanxiaozhong
 * @param jobName jobToken
 * @param groupName groupToken
 * @param cronExpress 
 */
//0 */20 * * * ? 每20分钟执行一次
public class RefreshTokenJob implements Job {

    //token实体类
    private static RefreshTokenConsumer consumer;
    static{
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        consumer = (RefreshTokenConsumer) context.getBean("refreshTokenThread");
    }

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        consumer.execute();
    }

}

这里使用了spring,我们只需要配置定时任务工厂类即可如:

<!-- 配置定时任务,用于初始化定时器 -->  
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
</bean>
<!-- 任务管理类 -->
<bean id="scheduleManager" class="com.realtech.model.ScheduleManager">
    <property name="scheduler" ref="schedulerFactoryBean"/>
</bean>
<!-- 定时任务之刷新token -->
<bean id="refreshTokenThread" class="com.realtech.consumer.RefreshTokenConsumer"> 
    <property name="key" value="authorization_access_token"/>
</bean>

在refreshTokenThread中实现具体的任务逻辑,RefreshTokenJob按照指定的重复规则每次都去执行execute方法

最后我们在main方法中完成任务的添加即可:

    package com.realtech.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.realtech.model.MessageJob;
import com.realtech.model.RedPacketsLogJob;
import com.realtech.model.RefreshTokenJob;
import com.realtech.model.ScheduleManager;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ScheduleManager manager = (ScheduleManager)context.getBean("scheduleManager");
        //添加token刷新任务
        manager.addJob("jobToken", "group3", RefreshTokenJob.class, "0 */20 * * * ?");
        System.out.println("开启任务1");
        manager.startAll();
        System.out.println("启动成功");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值