`

Spring定时器的两种实现方式二(quartz)

 
阅读更多

Quartz 是一个强大的企业级 Schedule 工具,也是目前最好的开源 Schedule 工具。Spring中也集成了quartz的应用,下面就讲一下如何在spring中使用quartz。

spring的配置:

xml 代码
  1. <beanid="schedulerFactoryBean"class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  2. <propertyname="triggers">
  3. <list>
  4. <refbean="simpleTrigger"/>
  5. <refbean="cornTrigger"/>
  6. </list>
  7. </property>
  8. </bean>
  9. <beanid="schedulerControl"class="com.pheh.scheduler.Schedule">
  10. <propertyname="scheduler">
  11. <refbean="schedulerFactoryBean"/>
  12. </property>
  13. </bean>
  14. <beanid="simpleTrigger"class="org.springframework.scheduling.quartz.SimpleTriggerBean">
  15. <propertyname="jobDetail">
  16. <refbean="methodInvokingJobDetail"/>
  17. </property>
  18. <propertyname="startDelay">
  19. <value>1000</value>
  20. </property>
  21. <propertyname="repeatInterval">
  22. <value>3000</value>
  23. </property>
  24. </bean>
  25. <beanid="cornTrigger"class="org.springframework.scheduling.quartz.CronTriggerBean">
  26. <propertyname="jobDetail">
  27. <refbean="methodInvokingJobDetail"/>
  28. </property>
  29. <propertyname="cronExpression">
  30. <value>00*/1**?</value>
  31. </property>
  32. </bean>

Job:
org.quartz.Job是一个接口,只定义了void execute(JobExecutionContext context)throws JobExecutionException;一个方法。当定时任务被触发后,系统会自动调用实现了该接口的方法。在spring中,org.springframework.scheduling.quartz.QuartzJobBean对其进行了封装,使用了Template Method模式。主要是为了在使用jobDataMap时更加方便。QuartzJobBean有两个方法,
public final void execute(JobExecutionContext context) throws JobExecutionException
Job接口中定义的,spring在该方法里进行了些处理,将jobDataMap中的值注入到该Job的实现者中

protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException
这是一个抽象方法,用户在扩展了QuartzJobBean后,要自己实现该方法,在其中添加相应的业务逻辑

JobDetail:
JobDetail描述了一个任务具体的信息。在Spring中,JobDetailBean对JobDetail进行了封装(继承了JobDetail)。
private String name;//名称
private String group = Scheduler.DEFAULT_GROUP;//组
private String description;//描述
private Class jobClass;//定时任务触发时,回调的class,该class要实现Job接口或继承QuartzJobBean
private JobDataMap jobDataMap;//该任务存储的数据,在回调的时候也可以使用
private boolean volatility = false;//是否持久化到org.quartz.spi.JobStore中
private boolean durability = false;//当该任务完成后,是否还在JobStore中继续保留该任务
private boolean shouldRecover = false;//当系统重新启动后,是否再次执行该任务
对于jobDataMap,它是是一个封装过的Map,使用方法同Map,如
jobDetailBean.getJobDataMap().put(target,value);
如果使用了QuartzJobBean,在使用jobDetailBean时,可将target的值设成QuartzJobBean的子类的属性名称,这样,在定时触发时,spring会自动将与target对应的value值注入到QuartzJobBean的子类中去。如。

java 代码
  1. ...
  2. publicclassReminderManagerextendsQuartzJobBean{
  3. privateStringreminderStr="";
  4. }
  5. ...
  6. jobDetailBean.getJobDataMap().put(reminderStr,"abcdefg");
  7. ...


这样当该任务被触发后,在ReminderManager中,reminderStr的值就会被注入为"abcdefg"。

Trigger:
trigger就是触发器。Quartz有个很好的想法就是分离了任务和任务执行的条件。Trigger就是控制任务执行条件的类,当Trigger认为执行条件满足的时刻,Trigger会通知相关的Job去执行。分离的好处是:
1.你可以为某个Job关联多个Trigger,其中任何一个条件满足都可以触发job执行,这样可以完成一些组合的高级触发条件
2.当Trigger失效后(比如:一个永远都不能满足的条件),你不必去声明一个新的job,代替的是你可以为job关联一个新的Trigger让job可以继续执行。
目前的Quartz实现中,存在两种Trigger,SimpleTrigger和CronTrigger,在spring中分别用SimpleTriggerBean和CronTriggerBean对其进行封装。SimpleTrigger是简单触发器,如从某日到某日,每个一定时间进行一次提醒,在这段时间内进行多少次提醒;CronTrigger是复杂触发器,用来执行calendar-like的任务,可设定一些复杂的触发规则,如每年的x月的第y个星期五,或是每个星期天的几点进行提醒。后面附加一个日常语义与cronTrigger的转化

Trigger
private String name;//名称
private String group = Scheduler.DEFAULT_GROUP;//组
private String jobName;//所关联的jobDetail的名称
private String jobGroup = Scheduler.DEFAULT_GROUP;//所关联的jobDetail的组
private String description;//描述
private JobDataMap jobDataMap;//该触发器存储的数据,在回调的时候也可以使用
private boolean volatility = false;//是否持久化到org.quartz.spi.JobStore中

SimpleTrigger
private Date startTime = null;//开始日期
private Date endTime = null;//结束日期
private Date nextFireTime = null;//下次的触发时间
private Date previousFireTime = null;//上次的触发时间
private int repeatCount = 0;//重复次数
private long repeatInterval = 0;//重复间隔
private int timesTriggered = 0;/已触发的次数

SimpleTriggerBean
private JobDetail jobDetail;//所关联的JobDetail,方便在配置文件中使用

CornTrigger
private CronExpression cronEx = null;//触发条件表达式,它有一个String型的setter
private Date startTime = null;//开始日期
private Date endTime = null;//结束日期
private Date nextFireTime = null;//下次的触发时间
private Date previousFireTime = null;//上次的触发时间
private transient TimeZone timeZone = null;//所在时区

CronTriggerBean
private JobDetail jobDetail;//所关联的JobDetail,方便在配置文件中使用

Scheduler的常用方法
添加一个定时任务:
Date scheduleJob(JobDetail jobDetail,Trigger trigger)

修改一个定时任务,主要是更改trigger:
Date rescheduleJob(String triggerName, String groupName, Trigger newTrigger)

删除一个定时任务,同时也会将于该jobDetail关联的trigger一并删除:
boolean deleteJob(String jobName,String jobGroup)

取得所有的jobDetail组
String[] getJobGroupNames()

取得某个group下的所有的jobDetail
String[] getJobNames(String groupName)

取得指定的jobDetail
JobDetail getJobDetail(String jobName, String jobGroup)

取得指定的jobDetail的所有的Trigger
Trigger[] getTriggersOfJob(String jobName, String groupName)

取得指定的Trigger
Trigger getTrigger(String triggerName, String triggerGroup)

Quartz的存储:
Quartz默认的是使用RAM存储所有的信息,但是这样的话,当我们重启服务器后,之前的所有的定时任务就全消失了。为了让服务器重启以后,我们的定时任务仍不丢失,我们可采用数据库持久化定时任务。
首先要先建立数据库,在quartz-1.6.0/docs/dbTables下,选择自己使用的数据库的sql脚本,建立相应的数据库表。
在WEB-INF下加一个quartz.properties。我们可以在 quartz-1.6.0/examples/example10 中找到该文件的样例

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX#表明使用JDBC进行持久化
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_#该值尽量不要改动,如改动,还要相应的修改sql脚本
org.quartz.jobStore.isClustered = false

org.quartz.dataSource.myDS.driver = net.sourceforge.jtds.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:jtds:sqlserver://192.168.1.101:1433/Northwind;autoReconnect=true
org.quartz.dataSource.myDS.user = sa
org.quartz.dataSource.myDS.password =
org.quartz.dataSource.myDS.maxConnections = 5


日常语义与cronTrigger的转化,以下setter,getter省略

java 代码
  1. publicclassTDateRange{
  2. privateintstartType=2;//开始类型。默认的使用2表示使用开始日期
  3. privateDatestartDate=newDate();//开始日期
  4. privateintendType=0;//结束类型。0表示无结束时间;1表示重复n次后结束;2表示使用结束日期
  5. privateDateendDate=newDate();//结束日期
  6. privateintoccurrences;//执行次数
  7. }
  8. publicclassTFrequency{
  9. //0:无重复提醒
  10. //1:每every
  11. //2:每个工作日detail=1,2,3,4,5
  12. //3:每every周后的星期detail日
  13. //4:每every月的detail日
  14. //5:每every月的第num1个星期num2
  15. //6:每年num1月num2日
  16. //7:每年every月的第num1个月的星期num2
  17. privateinttype=0;//频率类型
  18. privateintevery=0;
  19. privateStringdetail="";
  20. privateStringnum1="";
  21. privateStringnum2="";
  22. }
  23. privateStringformatQuartzString(){
  24. StringquartzStr="";
  25. tiggernote="";
  26. //秒分时
  27. quartzStr="0"+this.dateRange.getStartDate().getMinutes()+""+this.dateRange.getStartDate().getHours()+"";
  28. switch(this.frequency.getType()){
  29. case0://无重复提醒
  30. quartzStr+=this.dateRange.getStartDate().getDate()+""+(this.dateRange.getStartDate().getMonth()+1)+"?"+(this.dateRange.getStartDate().getYear()+1900);
  31. tiggernote+="起始时间:"+quartzStr;
  32. break;
  33. case1://每XX天提醒
  34. quartzStr+="*/"+this.frequency.getEvery()+"*?";
  35. tiggernote+="每"+this.frequency.getEvery()+"提醒";
  36. break;
  37. case2://每个工作日detail=1,2,3,4,5
  38. //quartzStr+="?*2-6";
  39. quartzStr="0*/1***?";//测试
  40. tiggernote+="每个工作日1,2,3,4,5提醒";
  41. break;
  42. case3://每every周后的星期detail日
  43. quartzStr+="?*"+this.frequency.getDetail()+"/"+this.frequency.getEvery();
  44. tiggernote+="每"+this.frequency.getEvery()+"周星期"+this.frequency.getDetail()+"日";
  45. break;
  46. case4://每every个月的detail日
  47. quartzStr+=this.frequency.getDetail()+"*/"+this.frequency.getEvery()+"?";
  48. tiggernote+="每"+this.frequency.getEvery()+"月"+this.frequency.getDetail()+"日";
  49. break;
  50. case5://每every个月的第num1个星期num2
  51. quartzStr+="?*/"+this.frequency.getEvery()+""+this.frequency.getNum2();
  52. //星期
  53. if(Integer.valueOf(this.frequency.getNum1()).intValue()>0){
  54. quartzStr+="#"+this.frequency.getNum1();
  55. tiggernote+="每"+this.frequency.getEvery()+"月第"+this.frequency.getNum1()+"个星期"+this.frequency.getNum2()+"日";
  56. }else{
  57. quartzStr+="L";
  58. tiggernote+="每"+this.frequency.getEvery()+"月星期"+this.frequency.getNum2();
  59. }
  60. break;
  61. case6://每年num1月num2日
  62. quartzStr+=this.frequency.getNum2()+""+this.frequency.getNum1()+"?";
  63. tiggernote+="每年"+this.frequency.getNum1()+"月"+this.frequency.getNum2()+"日";
  64. break;
  65. case7://每年every月的第num1个星期num2
  66. quartzStr+="?"+this.getFrequency().getEvery()+""+this.getFrequency().getNum2();
  67. //星期
  68. if(Integer.valueOf(this.frequency.getNum1()).intValue()>0){
  69. quartzStr+="#"+this.frequency.getNum1();
  70. tiggernote+="每年"+this.getFrequency().getEvery()+"月的第"+this.frequency.getNum1()+"个星期"+this.getFrequency().getNum2()+"日";
  71. }else{
  72. quartzStr+="L";
  73. tiggernote+="每年"+this.getFrequency().getEvery()+"月的"+this.getFrequency().getNum2()+"日";
  74. }
  75. break;
  76. default:
  77. }
  78. log.debug("quartzStr="+quartzStr);
  79. returnquartzStr;
  80. }
Scheduler:
Scheduler 是一个计划集,其中可以包含多个 JobDetail 和 Trigger 组成的计划任务。
在Quartz中,我们可以通过
SchedulerFactory scheduleFactory = new StdSchedulerFactory();
Scheduler scheduler = scheduleFactory.getScheduler();
来取得scheduler,通过调用scheduler.start()来启动quartz。
在spring中,org.springframework.scheduling.quartz.SchedulerFactoryBean是对Quartz的org.quartz.Scheduler的封装,通过上面的配置,在spring启动的时候,quartz就会跟随着启动,不需要再用scheduler.start()来启动。在spring中,如果要取得scheduler,可通过上面的配置文件那样,将SchedulerFactoryBean注入到schdeuler中

分享到:
评论

相关推荐

    spring定时器(内含TimerTask实现和Quartz实现两种方式)

    本篇文章将详细探讨两种实现Spring定时任务的方法:基于Java内置的`TimerTask`和第三方库Quartz Scheduler。 首先,让我们看看如何使用`TimerTask`来实现Spring中的定时任务。`TimerTask`是Java的标准库类,它提供...

    spring定时器两种实现方式

    Spring 定时器两种实现方式 Spring 定时器是 Spring 框架中的一种组件,用于实现定时任务的执行。它提供了两种实现方式:Java Timer 定时和 Quartz 定时器。在本文中,我们将详细介绍这两种实现方式的原理、优点和...

    spring 定时器的两种实现

    在Spring框架中,有两种主要的方法来实现定时任务:Spring自带的`@Scheduled`注解和引入第三方库Quartz。这两种方法都可以帮助开发者在特定的时间点执行任务,为应用程序添加计划任务的能力。 首先,我们来看看使用...

    spring定时器 Spring定时器的两种实现方式Java的Timer类和OpenSymphony的Quartz。

    Spring框架提供了两种方式来处理定时任务:Java内置的`Timer`类和第三方库OpenSymphony的Quartz。下面将详细介绍这两种实现方式。 ### 1. Java `Timer` 类 Java `java.util.Timer` 类是Java标准库中的一个轻量级...

    定时器的配置文件(两种方式:springmvc自带定时,Quartz与spring结合的定时)

    本篇文章将详细讲解两种在Spring MVC框架中实现定时任务的方法:Spring MVC自带的定时器以及Quartz与Spring的集成。 首先,我们来看看Spring MVC自带的定时任务。Spring MVC作为Spring框架的一个模块,主要处理HTTP...

    Spring定时器的两种实现方式.doc

    在Spring框架中,定时任务的实现通常有多种方式,这里主要讨论的是两种常见的方式:Java Timer和Quartz定时器。这两种方法都有其特点和适用场景,开发者可以根据项目需求来选择。 1. **Java Timer定时器** Java ...

    Spring定时器实例(Java的Timer类和OpenSymphony的Quartz)

    Spring两种定时器实例配置:Java的TimerTask类和OpenSymphony的Quartz。包含5种配置方式:timer普通定时器、timer特定方法定时器、quartz简单定时器、quartz精确定时器、quartz特定方法定时器。简单实用,一看就会。

    JAVA中 Spring定时器的两种实现方式

    在Java的Spring框架中,定时任务的实现有多种方式,其中两种常见的实现是基于Java的`Timer`类和OpenSymphony的`Quartz`库。这两种定时器在Spring中的使用和配置有所不同,各有优缺点,适合不同的应用场景。 1. **...

    SPRING 定时器的使用

    在Spring框架中,实现定时任务有两种主流方式:使用`java.util.Timer`类或集成第三方库如Quartz。这两种方法各有优势: - **Java Timer**:简单易用,适合简单的定时任务需求。 - **Quartz**:功能强大且灵活,支持...

    Spring自己的轻量级定时器的两种实现方式

    本篇文章将详细介绍两种使用Spring自身实现轻量级定时器的方法。 方法一:基于`@Scheduled`注解 1. `@Scheduled`注解:这是Spring提供的一个用于声明周期性任务的注解。在Java类中的方法上添加此注解,Spring会...

    spring定时器的包和配置文件

    Spring定时器基于Java的`java.util.Timer`和`java.util.TimerTask`,但更进一步,它支持Quartz和SimpleScheduler这两种强大的定时任务库。Quartz是一个开源的作业调度框架,而SimpleScheduler则内置在Spring中,适用...

    Spring定时器配置详解(附demo)

    Spring提供了两种主要的定时任务实现方式:`TaskScheduler`和`TaskExecutor`,以及基于Quartz的`SpringIntegration`模块。其中,`TaskScheduler`和`TaskExecutor`适用于简单的定时任务需求,如间隔执行或周期性执行...

    spring和quartz的定时器的启动和停止例子

    Spring提供了一种集成Quartz的方式,使得我们可以方便地在Spring应用中管理和执行定时任务。本篇将深入探讨如何在Spring中启动和停止Quartz定时器。 首先,我们需要理解Spring和Quartz的基本概念。Spring是一个强大...

    spring定时器-quartz开发的步骤

    首先,理解Spring定时器的基础概念。Spring提供了两种定时任务框架:`java.util.Timer`和`@Scheduled`注解。然而,对于复杂的企业级应用,Quartz更具有优势,因为它支持集群、灵活的调度策略和丰富的API。 1. **...

    spring定时器3.0之前和3.0之后以及相应的项目实例

    在提供的压缩包文件中,可能包含了使用上述两种方式实现的项目实例代码,你可以通过这些实例学习如何在不同的Spring版本下配置和使用定时任务。对于初学者来说,理解这些实例有助于深入掌握Spring的定时任务管理,并...

    spring 定时器

    Spring定时器主要支持两种方式来实现定时任务:基于注解的方式和基于Quartz集成的方式。 #### 二、Spring定时器的实现原理 ##### 2.1 基于注解的定时任务 Spring 3.0引入了`@Scheduled`注解,它可以直接添加到...

    spring学习系列 -- 定时器三 两种定时器的比较

    本文将深入探讨Spring提供的两种定时器——`Quartz`和`Spring Task`,并进行对比分析。 首先,让我们了解`Quartz`。Quartz是一个开源的作业调度框架,它允许应用程序在指定的时间执行任务。Quartz提供了丰富的API,...

    web spring 定时器

    首先,Spring提供了两种主要的定时任务解决方案:一是Spring内置的`TaskScheduler`接口,二是基于Quartz库的`@Scheduled`注解。`TaskScheduler`提供了一种异步执行任务的方式,适合于简单的定时任务需求。而`@...

    spring和java定时器

    Spring框架和Java内置的定时器提供了两种不同的方式来实现这样的功能。 首先,我们来看Spring定时器。Spring使用的是Quartz库来实现定时任务管理。在给出的例子中,可以看到配置文件中定义了几个关键的bean: 1. `...

    使用java定时器的几种方式

    在Java中实现定时任务有多种方式,...总之,Java中实现定时任务的三种主要方式各有特点,从简单的Timer到功能强大的Quartz再到易用的Spring Task,开发者可以根据自己的具体需求和场景,选择合适的定时任务实现方式。

Global site tag (gtag.js) - Google Analytics