Introduction:

Quartz Official Website:http://www.quartz-scheduler.org/

Quartz 是OpenSymphony开源组织在Job scheduling领域又一个开源项目。

Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中。

Quartz提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。


Quartz相对于java.util.Timer和java.util.TimerTask的优势:

1.主要的原因,适用不方便,特别是制定具体的年月日时分的时间,而quartz使用类似linux上的cron配置,很方便的配置每隔时间执行触发。
2.其次性能的原因,使用jdk自带的Timer不具备多线程,而quartz采用线程池,性能上比timer高出很多。


Dependent Jar:


Configuration:


quartz.properties

Quartz有一个叫做quartz.properties的配置文件,它允许你修改框架运行时环境。缺省是使用Quartz.jar里面的quartz.properties文件。当然,你应该创建一个quartz.properties文件的副本并且把它放入你工程的classes目录中以便类装载器找到它。

#============================================================================
# Configure Main Scheduler Properties  
#============================================================================
org.quartz.scheduler.instanceName = DataSysScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool  
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class =org.quartz.simpl.RAMJobStore
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = quartz_job.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.scheduler.skipUpdateCheck = true 


quartz_job.xml
<?xml version="1.0" encoding="UTF-8"?>  
<job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
    version="1.8">
    
	<pre-processing-commands>
		<delete-jobs-in-group>*</delete-jobs-in-group>  <!-- clear all jobs in scheduler -->
		<delete-triggers-in-group>*</delete-triggers-in-group> <!-- clear all triggers in scheduler -->
	</pre-processing-commands>
	<processing-directives>
		<!-- if there are any jobs/trigger in scheduler of same name (as in this file), overwrite them -->
		<overwrite-existing-data>true</overwrite-existing-data>
		<!-- if there are any jobs/trigger in scheduler of same name (as in this file), and over-write is false, ignore them rather then generating an error -->
		<ignore-duplicates>false</ignore-duplicates> 
	</processing-directives>
	
	<schedule>
		<job>
	        <name>ParseDataJob</name>
            <group>DataSys</group>
            <description>数据解析job</description>
	        <job-class>esmart.datasys.quartzjob.ParseDataJob</job-class>
	        <volatility>false</volatility>
            <durability>true</durability>
            <recover>false</recover>
	    </job>
	    <trigger>
	        <cron>
	            <name>ParseDataTrigger</name>
	            <group>DataSys</group>
	            <job-name>ParseDataJob</job-name>
	            <job-group>DataSys</job-group>
                <misfire-instruction>MISFIRE_INSTRUCTION_FIRE_ONCE_NOW</misfire-instruction>
	            <cron-expression>0/20 * * * * ?</cron-expression>
	        </cron>
	    </trigger>
	</schedule>
	
</job-scheduling-data>

其中的 <job-class> 是自己定义的实现org.quartz.Job接口,有一个空的构造函数的类。


与J2ee容器结合,提供QuartzInitializerListener,可设定随容器自动启动。web.xml

<?xml version="1.0" encoding="UTF-8"?>   
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">   
  
  <display-name>Foo Batch</display-name>   
  
  <context-param>   
    <param-name>quartz:config-file</param-name>   
    <param-value>/quartz.properties</param-value>   
  </context-param>   
  
  <listener>   
    <listener-class>   
       org.quartz.ee.servlet.QuartzInitializerListener   
    </listener-class>   
  </listener>   
  
  </web-app>  


 

API:

1.SchedulerFactory

    产生计划实例的工厂类。

 

2.Scheduler

   计划管理类。计划的启动,停止等。这个实例里面能够事先把Job和Trigger加进去。

 

3.Job
   在计划中执行的job的接口。需要实装Job#execute(JobExecutionContext) 这个接口。具体作业要做的逻辑就写在这个类里面。

4.JobExecutionContext
   Job#execute(JobExecutionContext)这个方法的参数类型。job的所有参数都保存在这个类的 JobDetail里面。

5.JobDetail
   Job的具体信息。job名,group名,job类。这写信息是在这个job加入到计划实例的时候生成的。

6.JobDataMap
   Map接口的派生类。具体的参数都保存这个对象里面。JobDetail 和Trigger对象的 #getJobDataMap() 方法可以取到该对象。

7.Trigger
   job的触发类。一般主要到两类触发器就是SimpleTrigger 和 CronTrigger 。

8.SimpleTriggr
   只执行一次的。即时实行或者预约执行。

9.CronTrigger
   根据设定的日历信息定期执行。


10.StatefulJob
   使用StatefulJob的场合,Job#execute(JobExecutionContext)执行完后,JobDataMap对象的信息继续保存。

11.Calendar
   这个类并不是java.util.Calendar。Scheduler#addCalendar() 方法登录。

12.Trigger的优先顺序
   同一时间有多个触发的时候,那一个优先?可以设置优先度 priority 。


13.TriggerListener
   能够设置Trigger的 fire事件的时候通知那一个TriggerListener。

 

14.Listener

   job执行要执行,job执行失败,job执行完了等三个接口。这样就可以跟踪job的执行状况。


Quartz Structure:

   
Quartz Develop Practice One_sed
 

        错误:trigger为一Abstract类而非Interface

 

Job: 任务接口,必须存在一public无参构造方法,要调度的任务必须实现此接口。

 

JobDetail: Quartz不直接使用Job接口,而是通过JobDetail来使用Job接口,JobDetail中有一属性为Class jobClass,

                   这也是实现Job接口时必须存在一public无参构造方法的原因。可通过JobDataMap向Job传输数据。

           每一个Job都有一个jobName和groupName与之对应,并且在同一个Scheduler中必须唯一。

 

Trigger: 任务执行的条件。

          每一个Trigger都有一个name和group与之对应,并且在同一个Scheduler中也必须唯一。

          一个Trigger只能指向一个JobDetail,而不同的Trigger可以指向同一个JobDetail。

                 可以通过JobDataMap向Job传输数据。

 

SimpleTrigger: Trigger的子类,根据一定频率以及次数对任务进行调度。

 

CronTrigger: Trigger的子类,根据Cron表达式对任务进行调度。

                       关于Cron表达式可参考附件详解。

 

Scheduler: 对在其内注册的JobDetail根据相应的Trigger进行调度。

                   通过SchedulerFactory生成实例。