前序:
     我们已经大概对Quartz的基本有了一个大概的认识;现在我们将要逐渐对Quartz的各个重要组件进行学习;前面已经对job进行了详细讲解,现在我们来认识下它的一个重要兄弟,没有它,作业将无法得到执行的---触发器Trigger;

1.Quartz中的触发器Trigger

  Job 包含了要执行任务的逻辑,但是 Job 对何时该执行却一无所知。这个事情留给了 Trigger。Quartz Trigger 继承了抽象的 org.quartz.Trigger 类。当前,Quartz 有三个可用的 Trigger:

  1. ·org.quartz.SimpleTrigger
  2. ·org.quartz.CronTrigger
  3. ·org.quartz.NthIncludeDayTrigger

2.SimpleTrigger的介绍

   正如其名所示,SimpleTrigger对于设置和使用是最为简单的一种 Quartz Trigger。它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行 n  次的 Job 所设计的。

   我们前面已经在一个简单的Quartz的例子里使用过了SimpleTrigger,我们通过

  1. Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);

来获取到我们的Trigger,而得到的实际上就是SimpleTrigger类的一个实现;我们实际上

还可以对上面的代码进行小小的改造:

  1. /*
  2. * Create a SimpleTrigger that starts immediately,
  3. * with a null end date/time, repeats forever and has
  4. * 1 minute (60000 ms) between each firing.
  5. */
  6. Trigger trigger =
  7. new SimpleTrigger("myTrigger",Scheduler.DEFAULT_GROUP,
  8. new Date(),null,SimpleTrigger.REPEAT_INDEFINITELY,60000L);

对于Quartz而言,它还不能满足我们的触发情况,所以它仅仅是用于一些简单的触发情况;

3.org.quartz.CronTrigger

  CronTrigger 允许设定非常复杂的触发时间表。然而有时也许不得不使用两个或多个 SimpleTrigger
来满足你的触发需求,这时候,你仅仅需要一个 CronTrigger 实例就够了。顾名思义,CronTrigger 是基于 Unix 类似于
cron 的表达式。例如,你也许有一个 Job,要它在星期一和星期五的上午 8:00-9:00 间每五分钟执行一次。假如你试图用
SimpleTrigger 来实现,你或许要为这个 Job 配置多个 Trigger。然而,你可以使用如下的表达式来产生一个遵照这个时间表触发的
Trigger;

比如:

  1. try {
  2. CronTrigger cTrigger = new CronTrigger("myTrigger",
  3. Scheduler.DEFAULT_GROUP, "0 0/5 8 ? *
  4. MON,FRI");
  5. } catch (ParseException ex) {
  6. ex.printStackTrace();
  7. }

因为 CronTrigger
内建的如此强的灵活性,也与生俱来可用于创建几乎无所限制的表达式,且因为支持unix的cron表达式,则做为企业应用,我们的操作系统一般也都以
unxi操作系统为主,所以掌握CronTrigger 的使用费用有必要,我们将在后面对CronTrigger 进行详细的介绍;

4.org.quartz.NthIncludedDayTrigger

   org.quartz.NthIncludedDayTrigger 是 Quartz 开发团队最新加入到框架中的一个
Trigger。它设计用于在每一间隔类型的第几天执行 Job。例如,你要在每个月的 15 号执行开票的 Job,用
NthIncludedDayTrigger就再合适不过了。Quartz的 Caldendar 也可与 Trigger
关联以此把周末与节假日考虑进来,并在必要时跳开这些日期。接下来的代码片断描绘了如何创建一个 NthIncludedDayTrigger.

  1. NthIncludedDayTrigger trigger =
  2. new NthIncludedDayTrigger("MyTrigger",Scheduler.DEFAULT_GROUP);
  3. trigger.setN(15);
  4. trigger.setIntervalType(NthIncludedDayTrigger.INTERVAL_TYPE_MONTHLY);

5.Job与Trigger的关系

   大家都知道,一个作业,比较重要的三个要素就是Schduler,jobDetail,Trigger;

而Trigger对于job而言就好比一个驱动器;没有触发器来定时驱动作业,作业就无法运行;

对于Job而言,一个job可以对应多个Trigger,但对于Trigger而言,一个Trigger只能对应一个job;所以一个 Trigger 只能被指派给一个 Job;

   如果你需要一个更复杂的触发计划,你可以创建多个 Trigger 并指派它们给同一个 Job。Scheduler 是基于配置在 Job 上的 Trigger 来决定正确的执行计划的,下面就是为同一个 JobDetail 使用多个Trigger;

  1. try {
  2. // 创建一个任务调度器
  3. Scheduler scheduler=StdSchedulerFactory.getDefaultScheduler();
  4. scheduler.start();
  5. logger.info("Scheduler has been started");
  6. //为一个作业类创建一个作业明细
  7. JobDetail jobDetail =new JobDetail("PrintInfoJob",Scheduler.DEFAULT_GROUP,PrintInfoJob.class);
  8. //省略为jobDetail设置JobDataMap的代码
  9. //创建一个触发器1,每5S触发一次
  10. Trigger trigger1 =TriggerUtils.makeSecondlyTrigger("trigger1",5000, SimpleTrigger.REPEAT_INDEFINITELY);
  11. //创建一个触发器1,每10S触发一次
  12. Trigger trigger2 =TriggerUtils.makeMinutelyTrigger("trigger2", 10,
  13. SimpleTrigger.REPEAT_INDEFINITELY);
  14. //将作业在任务调度器上进行注册
  15. scheduler.scheduleJob(jobDetail,trigger1);
  16. scheduler.scheduleJob(jobDetail, trigger2);
  17. } catch (SchedulerException ex) {
  18. logger.error(ex);
  19. }

我们可以看出了,将一个作业注册到任务调度器上,并非以Job来进行识别,而是作业对应的触发器;也就是可以理解为,在该任务调度器上,如果你这个作业任务可能在不同的时间点被启动多次,且并非周期性的(即触发点有多个),则你需要在该任务调度器上注册多次;

6.Trigger的另一个重要内容--Calendar

  
Calendar在java里,它的概念目前做为日历类来进行使用,并且多用于日期类的计算和处理;但我们在Quartz里的calendar则不是这个
概念,而Quartz 的 Calender 专门用于屏闭一个时间区间,使 Trigger 在这个区间中不被触发;

   

    ·让你的 Job 总是运行。(这会让银行一团糟)

·在节假日期间手动停止你的 Job。(需要专门的人来负责做这个事情)

·创建不包含这些日子的多个 Trigger。(这对于设置和维护会较耗时的)

·设立一个排除这些日子的银行节日的 Calendar。(很轻松的实现)

我们可以认为它就是一个屏蔽区域,例如,让我们假如你是为一个财务机构(如银行)工作。对于银行普遍的都有许多
"银行节日"。假设你不需要(或不想) Job
在那些日子里运行。那么只要设置一个这样的Calendar就可以了,这样就可以实现指定时间里,这些作业不会周期的执行了;

    Quartz的Calendar接口,有许多实现,它们可以帮助我们应对各种隔离区间的表示,下面我们就来仔细认识下它们;

org.quartz.Calender 接口

public interface Calendar extends java.io.Serializable {

    /*

     *接口中定义的隔离区间是以月份为单位,即某月的某段日期

      */

    int MONTH = 0;

    /**

     * <p>

     * 设置一个新的calendar实例,或删除掉旧的calendar实例

     * </p>

     */

    void setBaseCalendar(Calendar baseCalendar);

/**

     * <p>

     * 获得到当前的calendar实例

     * </p>

     */

    Calendar getBaseCalendar();

/**

     * <p>

     * 设定屏蔽作业启动的时间;

     * </p>

     */

    boolean isTimeIncluded(long timeStamp);

/**

     * <p>

     *  根据指定的时间,获取到下一次屏蔽区域的时间,比如今天做为作业

      *  作业屏蔽的时间,则按照指定屏蔽的规则,我们就可以知道下一次的屏蔽时间;

     * </p>

     */

    long getNextIncludedTime(long timeStamp);

/**

     * <p>

     * 获取当前Calendar对应的描述信息;

      * </p>

     */

    String getDescription();

/**

     * <p>

     * 当前Calendar对应的描述信息,可以设置它来说明设置当前Calendar的

      * 设置目的和意义;

     * </p>

     */

    void setDescription(String description);

}

下面是Quartz提供给用户可以使用的已实现Calendar类;Calender

BaseCalender

org.quartz.impl.calendar.BaseCalender为高级的 Calender 实现了基本的功能,实现了 org.quartz.Calender 接口

WeeklyCalendar

org.quartz.impl.calendar.WeeklyCalendar排除星期中的一天或多天,例如,可用于排除周末

MonthlyCalendar

org.quartz.impl.calendar.MonthlyCalendar排除月份中的数天,例如,可用于排除每月的最后一天

AnnualCalendar

org.quartz.impl.calendar.AnnualCalendar排除年中一天或多天

HolidayCalendar

org.quartz.impl.calendar.HolidayCalendar特别的用于从 Trigger 中排除节假日

大家请注意:

  对于Calendar,它可以为多个job服务,也就是它可以做为一个公共的信息,与多个Trigger进行绑定;而并不与Trigger一样,只能对应一个Job;

Calendar的使用方式如下:

   要使用 Quartz Calendar,你只需简单的实例化,并加入你要排除的日期,然后用 Scheduler 注册它。最后把这个 Calender 实例与你想要使用该 Calender 的每一个 Trigger 实例关联起来。

a.使用WeeklyCalendar

    排除星期中的一天或多天,例如,可用于排除周末;我们假定每周日做为休息日期,不执行某作业的执行;

    下面是它的应用

  1. LogUtil.print("将作业注册到调度器上");
  2. Scheduler scheduler=this.getScheduler();
  3. String dirPath = "E:\\重要";
  4. String matchName = ".rar";
  5. //设置JobDataMap
  6. JobDataMap jobDataMap=new JobDataMap();
  7. jobDataMap.put("SCAN_DIR", dirPath);
  8. jobDataMap.put("MATCH_NAME", matchName);
  9. //设置JobDetail
  10. JobDetail jobDetail = new JobDetail
  11. ("ScanDirectory",scheduler.DEFAULT_GROUP, ScanDirectoryJob.class);
  12. jobDetail.setJobDataMap(jobDataMap);
  13. //创建以周做为周期的触发器
  14. WeeklyCalendar cal = new WeeklyCalendar();
  15. boolean[] excludeDays = new boolean[8];
  16. excludeDays[1]=true; //周日
  17. excludeDays[2]=false;//周1
  18. excludeDays[3]=false;//周2
  19. excludeDays[4]=false;//周3
  20. excludeDays[5]=false;//周4
  21. excludeDays[6]=false;//周5
  22. excludeDays[7]=true; //周6
  23. cal.setDaysExcluded(excludeDays);
  24. //将触发器对应的Calendar注册在任务调度器上
  25. scheduler.addCalendar("bankHolidays", cal, true, true);
  26. Trigger trigger =
  27. TriggerUtils.makeImmediateTrigger("myTrigger",-1,6000);
  28. trigger.setCalendarName("bankHolidays");
  29. //注册作业到任务调度器(作业明细与触发器对象)
  30. scheduler.scheduleJob(jobDetail, trigger);

在上面的代码中,当我们在周末执行该文件扫描任务的时候,任务将不会被执行;而当起他时间点的时候,该任务才会被执行;

b.使用MonthlyCalendar

企业级任务调度框架Quartz(9) Quartz之作业触发器Trigger的更多相关文章

  1. Quartz:不要重复造轮子,一款企业级任务调度框架。

    背景 第一次遇到定时执行某些任务的需求时,很多朋友可能设计了一个小类库,这个类图提高了一个接口,然后由调度器调度所有注册的接口类型,我就是其中之一,随着接触的开源项目越来越多,我的某些开发习惯受到了影 ...

  2. 企业级任务调度框架Quartz(8) 线程在Quartz里的意义(2)

    前序:      做为企业里的任务调度框架,出现同一时间点同时运行两个任务,或者两个任务因为开始的执行时间和执行时间的长短,很有可能出现任务并发执行的情况:因为Quartz的实现是采用java编程,那 ...

  3. 企业级任务调度框架Quartz(5) Quartz的声明式配置

    前序:     前面我们已经通过编程的方式实现了多个作业任务执行具体操作的演示:但具体到实际的时候,如果我们要在 Job 启动之后改变它的执行时间和频度,则必须去修改源代码重新编译,我们很难去以编程的 ...

  4. 企业级任务调度框架Quartz(3) 一个简单的Quartz 例子

    1. 一个简单的Quartz 工程     本示例应用比起众所周知的 System.out.println("Hello world from Quartz") 来还是要有趣些.当 ...

  5. 企业级任务调度框架Quartz(1) --企业应用中的任务调度介绍

    由于目前的工作内容为建行CLPM批处理业务的设计工作,所以很好的理解批处理所用的任务调度框架Quartz势在必行:为了能够更好的去服务于工作,也 为了提升自己,所以我学习了Quartz Job Sch ...

  6. 企业级任务调度框架Quartz(4) 多个job实例注册到任务调度器上

    前序:     在第一个例子我看到了自定义的作业类在任务调度器上注册后,则通过任务调度器来实现启动:下面,我们将同一个作业类执行两个任务,并都将他们注册到任务调度器上!     首先一个job类指向两 ...

  7. 企业级任务调度框架Quartz(2)-下载和安装Quartz

    1.下载和安装 Quartz 根据资料上提供的网址http://www.opensymphony.com/quartz 我们可以下载到Quartz的最新版本1.6.4: 2.下载后包的说明       ...

  8. Quartz(自动任务)中的触发器Trigger

    1.Quartz中的触发器TriggerJob 包含了要执行任务的逻辑,但是 Job 对何时该执行却一无所知.这个事情留给了 Trigger.Quartz Trigger 继承了抽象的 org.qua ...

  9. 企业级任务调度框架Quartz(6) 任务调度器(Scheduler)

    前序:      我们已经在前面的内容能里看到了,我们用 Scheduler 来管理我们的 Job:创建并关联触发器以使 Job 能被触发执行:以及如可选择 calendar 为给定的时程安排提供更多 ...

随机推荐

  1. Codeforces 816A/B

    A. Karen and Morning 传送门:http://codeforces.com/contest/816/problem/A 水题,参考程序如下: #include <stdio.h ...

  2. spring-boot 访问时,加与不加项目名分析

    众所周知,springboot非常便捷,可以简化项目开启步骤,加快开发进度. 很多新手也许都遇到过这样一个问题,在以往的springMvc项目里,大家伙都是把打的war放在tomcat中运行,下意识的 ...

  3. vscode简单使用介绍及个人常用扩展插件

    vscode全称Visual Studio Code 是微软开发一款IDE,官方地址 vscode  作为一款前端编辑器功能很强大,灵活,可以根据个人喜好选择扩展插件,而且还支持多种开发语言, 关于v ...

  4. OpenCV实现USM锐化与测试

    OpenCV实现USM锐化 [转]http://www.programdevelop.com/4964391/ USM (Unsharp masking) is a common operation ...

  5. Spring Boot学习总结(3)——SpringBoot魅力所在

    使用Java做Web应用开发已经有近20年的历史了,从最初的Servlet1.0一步步演化到现在如此多的框架,库以及整个生态系统.经过这么长时间的发展,Java作为一个成熟的语言,也演化出了非常成熟的 ...

  6. jvm学习-垃圾回收器(四)

    说明 各种垃圾回收算法都有各自的优缺点.jvm也并没有只采用一种垃圾算法.并提供几种组合供我根据场景进行选择. jvm内存结构 Person p=new Person(); 1.程序里面创建一个对象会 ...

  7. java extend 和 implements 的区别

    1. 在类的声明中,通过关键字extends来创建一个类的子类.一个类通过关键字implements声明自己使用一个或者多个接口.extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重 ...

  8. [bzoj1195][HNOI2006]最短母串_动态规划_状压dp

    最短母串 bzoj-1195 HNOI-2006 题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串. 注释:$1\le n\le 12$,$1\le ...

  9. AIX中查看进程内存使用

    AIX中查看进程内存使用 学习了:http://www.2cto.com/os/201308/235858.html 1,从大到小排列10个内存使用率进程 ps aux |  head -1 ;  p ...

  10. [Javascript] IntersectionObserver -- Lazy Load Images on a Website

    When it comes to websites performance is king. How long it takes for a page to load can mean the dif ...