JAVA创建quartz-2.2.3定时任务(简单案例)

Job与JobDetail是Quartz用来定义具体任务的,而Trigger则是用来定义任务如何执行的。Quartz提供了Trigger接口来定义公共属性,使用TriggerBuilder可以创建具体类型的Trigger;最常见的两种Trigger分别是SimpleTrigger、CronTrigger。重点说一下Trigger。

一、概念

Trigger的公共属性:

  • key,该属性是为了标识Trigger的。
  • startTime,Trigger第一次被Scheduler触发的时间;该属性的值是指定某个时间点的java.util.Date对象。
  • endTime,Trigger不再被执行的时间。
  • priority,优先级;通过设置优先级属性可以控制Trigger被执行的顺序,该属性默认值是5,可以为正整数也可以为负整数。需要注意的是,只有在触发时间相同时,优先级属性才会有效;比如10:59执行的任务总是会在11:00执行的任务之前执行;另外,如果Trigger是可恢复的,那么恢复后,优先级是不会改变的。
  • misfire,如果因为某些原因,错过触发时间,就需要使用该属性来调整。不同类型的Trigger拥有不同的misfire,但是默认的是smart policy,这种情况下会根据Trigger的类型与配置来动态的调整行为。
  • Calendars,该属性并不是java.util.Calendar类型,它的作用是排除某些时间,比如在周末不执行任务。Quratz的Calendar对象是一个实现了Calendar接口的序列化对象,Calendars接口如下:
package org.quartz;    
public interface Calendar {    
  public boolean isTimeIncluded(long timeStamp);    
  public long getNextIncludedTime(long timeStamp);    
}
这两个方法都是精确到毫秒的;如果只是排除以天为单位的时间,可以使用HolidayCalendar。 

Calendars必须实例化,然后通过Scheduler的addCalendar()方法注册。Calendars可以重复使用,如下代码:

Trigger trigger1 = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "test")
                .startAt(DateBuilder.futureDate(3, IntervalUnit.SECOND))
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInMilliseconds(5000)
                        .withIntervalInSeconds(5)
                        .withRepeatCount(5))
                .modifiedByCalendar("holidayCalendar")
                .build();

Trigger trigger2 = TriggerBuilder.newTrigger()
                .withIdentity("trigger2", "test")
                .startAt(DateBuilder.futureDate(3, IntervalUnit.SECOND))
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInMilliseconds(5000)
                        .withIntervalInSeconds(5)
                        .withRepeatCount(5))
                .modifiedByCalendar("holidayCalendar")
                .build();

SimpleTrigger

下面来看SimpleTrigger。通过之前的例子可以看到如何创建Trigger,首先通过TriggerBuilder.newTrigger()方法建立一个TriggerBuilder对象,然后通过withSchedule()方法指定了SimpleScheduleBuilder,最后build()方法构建出了SimpleTrigger对象。 
SimpleTrigger很简单,之前例子中创建的都是SimpleTrigger,任务启动后每隔5s运行一次,总共运行5次。Quartz提供了DateBuilder工具类来方便设置时间,里面提供了很多方法,如上面Trigger2设置的启动时间就是3秒后启动任务。

CronTrigger

CronTrigger使用cron表达式来设置触发时间。CronTrigger创建方式:

Trigger trigger3 = TriggerBuilder.newTrigger()
                .withIdentity("cron trigger", "test")
                .withSchedule(
                    //每5秒执行一次                       
                    CronScheduleBuilder.cronSchedule("0/5 * * ? * *")
                ).build();

二、简单案例

编写任务调度工具类:

package com.utils;

import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 任务调度公共类
 *
 * @author iaiai QQ:176291935
 * @remark
 * @time 2015-3-23下午3:04:12
 */
public class QuartzUtil {

    private final static String JOB_GROUP_NAME = "QUARTZ_JOBGROUP_NAME";//任务组
    private final static String TRIGGER_GROUP_NAME = "QUARTZ_TRIGGERGROUP_NAME";//触发器组
    private static Logger log = LoggerFactory.getLogger(QuartzUtil.class);//日志

    /**
     * 添加任务的方法
     *
     * @param jobName     任务名
     * @param triggerName 触发器名
     * @param jobClass    执行任务的类
     * @param seconds     间隔时间
     * @throws SchedulerException
     */
    public static void addJob(String jobName, String triggerName, Class jobClass, int seconds) throws SchedulerException {
        log.info("==================initialization=================");

        //创建一个SchedulerFactory工厂实例
        SchedulerFactory sf = new StdSchedulerFactory();

        //通过SchedulerFactory构建Scheduler对象
        Scheduler sche = sf.getScheduler();

        log.info("===================initialize finshed===================");

        log.info("==============add the Job to Scheduler==================");

        //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(jobName, JOB_GROUP_NAME)
                .build();

        //构建一个触发器,规定触发的规则
        Trigger trigger = TriggerBuilder.newTrigger()//创建一个新的TriggerBuilder来规范一个触发器
                .withIdentity(triggerName, TRIGGER_GROUP_NAME)//给触发器起一个名字和组名
                .startNow()//立即执行
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule()
                                .withIntervalInSeconds(seconds)//时间间隔  单位:秒
                                .repeatForever()//一直执行
                        //CronTrigger使用cron表达式来设置触发时间。CronTrigger创建方式:
                        //CronScheduleBuilder.cronSchedule("0 53 19 ? * *")     [[秒] [分] [小时] [日] [月] [周] [年] 当前为每天下午7点53执行
                )
                .build();//产生触发器

        //向Scheduler中添加job任务和trigger触发器
        sche.scheduleJob(jobDetail, trigger);

        //启动
        sche.start();
    }
}

编写实际任务执行类,执行实际的业务操作:

package com.utils;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Date;

public class QuartzJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("this is the job execute method" + new Date());
    }
}

编写测试类:

package com.test;

import com.utils.QuartzJob;
import com.utils.QuartzUtil;
import org.quartz.*;

public class jobTest {
    public static void main(String[] args) {
        try {
            QuartzUtil.addJob("job1", "trigger1", QuartzJob.class, 2);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

三、附录:CronExpression表达式

格式:[秒] [分] [时] [每月的第几日] [月] [每周的第几日] [年]

字段名 必须的 允许值 允许的特殊字符
Seconds YES 0-59 , - * /
Minutes YES 0-59 , - * /
Hours YES 0-23 , - * /
Day of month YES 1-31 , - * ? / L W
Month YES 1-12 or JAN-DEC , - * /
Day of week YES 1-7 or SUN-SAT , - * ? / L #
Year NO empty, 1970-2099 , - * /

特殊字符说明:

字符 含义
* 用于 指定字段中的所有值。比如:* 在分钟中表示 每一分钟
? 用于 指定日期中的某一天,或是 星期中的某一个星期
- 用于 指定范围。比如:10-12 在小时中表示 10 点,11 点,12 点
, 用于 指定额外的值。比如:MON,WED,FRI 在日期中表示 星期一, 星期三, 星期五
/ 用于 指定增量。比如:0/15 在秒中表示 0 秒, 15 秒, 30 秒, 45 秒5/15 在秒中表示 5 秒,20 秒,35 秒,50 秒
L 在两个字段中拥有不同的含义。比如:L 在日期(Day of month)表示 某月的最后一天。在星期(Day of week)只表示 7 或 SAT。但是,值L 在星期(Day of week)中表示 某月的最后一个星期几。 比如:6L 表示 某月的最后一个星期五。也可以在日期(Day of month)中指定一个偏移量(从该月的最后一天开始).比如:L-3 表示 某月的倒数第三天
W 用于指定工作日(星期一到星期五)比如:15W 在日期中表示 到 15 号的最近一个工作日。如果第十五号是周六, 那么触发器的触发在 第十四号星期五。如果第十五号是星期日,触发器的触发在 第十六号周一。如果第十五是星期二,那么它就会工作开始在 第十五号周二。然而,如果指定 1W 并且第一号是星期六,那么触发器的触发在第三号周一,因为它不会 "jump" 过一个月的日子的边界。
L和 W 可以在日期(day-of-month)合使用,表示 月份的最后一个工作日
# 用于 指定月份中的第几天。比如:6#3 表示 月份的第三个星期五(day 6 = Friday and "#3" = the 3rd one in the month)。其它的有,2#1 表示 月份第一个星期一4#5 表示 月份第五个星期三。注意: 如果只是指定 #5,则触发器在月份中不会触发。

注意:字符不区分大小写,MON 和 mon 相同。

cronExpression 示例

表达式 含义
0 0 12 * * ? 每天中午 12 点
0 15 10 ? * * 每天上午 10 点 15 分
0 15 10 * * ? 每天上午 10 点 15 分
0 15 10 * * ? * 每天上午 10 点 15 分
0 15 10 * * ? 2005 在 2005 年里的每天上午 10 点 15 分
0 * 14 * * ? 每天下午 2 点到下午 2 点 59 分的每一分钟
0 0/5 14 * * ? 每天下午 2 点到 2 点 55 分每隔 5 分钟
0 0/5 14,18 * * ? 每天下午 2 点到 2 点 55 分, 下午 6 点到 6 点 55 分, 每隔 5 分钟
0 0-5 14 * * ? 每天下午 2 点到 2 点 5 分的每一分钟
0 10,44 14 ? 3 WED 3 月每周三的下午 2 点 10 分和下午 2 点 44 分
0 15 10 ? * MON-FRI 每周一到周五的上午 10 点 15 分
0 15 10 15 * ? 每月 15 号的上午 10 点 15 分
0 15 10 L * ? 每月最后一天的上午 10 点 15 分
0 15 10 L-2 * ? 每月最后两天的上午10点15分
0 15 10 ? * 6L 每月的最后一个星期五的上午 10 点 15 分
0 15 10 ? * 6L 2002-2005 2002 年到 2005 年每个月的最后一个星期五的上午 10 点 15 分
0 15 10 ? * 6#3 每月的第三个星期五的上午 10 点 15 分
0 0 12 1/5 * ? 每月的 1 号开始每隔 5 天的中午 12 点
0 11 11 11 11 ? 每年 11 月 11 号上午 11 点 11 分

你可能感兴趣的:(Java,quartz)