參考文章:https://blog.csdn.net/chen3749102/article/details/53431470
https://blog.csdn.net/shasiqq/article/details/51023762
http://www.cnblogs.com/drift-ice/p/3817269.html
一、quartz是現在常用的定時任務框架之一。
二、代碼入門:採用常見的 spring-maven架構。
2.1 pom.xml添加:
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
2.2 spring的applicationContext.xml的配置信息裏面加上如下定義的代碼:
<!-- 工作的bean -->
<bean id="myJob" class="com.haoxin.web.ops.ad.util.QuartzJob" />
<!-- job的配置開始 -->
<bean id="myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="myJob" />
</property>
<property name="targetMethod">
<value>work</value>
</property>
</bean>
<!-- job的配置結束 -->
<!-- 調度的配置開始 -->
<bean id="crontestJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="myJobDetail" />
</property>
<property name="cronExpression">
<value>10 0/1 * * * ?</value> <!-- Cron表達式“10 */1 * * * ?”意爲:從10秒開始,每1分鐘執行一次。 -->
</property>
</bean>
<!-- 調度的配置結束 -->
<!-- 啓動觸發器的配置開始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="crontestJobTrigger" />
</list>
</property>
</bean>
<!-- 啓動觸發器的配置結束 -->
至此,環境就搭好了。
2.3 定義一個Quartz的實現類,要實現Job接口或StatefulJob接口,並覆寫execute方法:
package com.luo.quartzTest;
import java.util.Date;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
public class HelloQuartz implements StatefulJob {
public HelloQuartz() {
}
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
String name = detail.getJobDataMap().getString("name");
System.out.println("say hello to " + name + " at " + new Date());
}
}
2.4 寫一個job定時任務的測試類,其實這個類裏的代碼可以寫在上面定義的那個類裏面,這裏爲了方便代碼複用,另寫一個。
package com.luo.quartzTest;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.DateBuilder.newDate ;
import static org.quartz.JobBuilder.newJob ;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule ;
import static org.quartz.TriggerBuilder.newTrigger ;
public class QuartzTest {
public QuartzTest() {
// TODO 自動生成的構造函數存根
}
public static void main(String[] args) {
// TODO 自動生成的方法存根
try {
//創建scheduler
Scheduler scheduler = StdSchedulerFactory . getDefaultScheduler ();
//定義一個Trigger
Trigger trigger = newTrigger().withIdentity( "trigger1" , "group1" )
.startNow() //一旦加入scheduler,立即生效
.withSchedule(simpleSchedule() //使用SimpleTrigger
.withIntervalInSeconds(1)//每隔一秒執行一次
.repeatForever()) //一直執行,奔騰到老不停歇
.build();
//定義一個JobDetail
JobDetail job = newJob(HelloQuartz.class) //定義Job類爲HelloQuartz類,這是真正的執行邏輯所在
.withIdentity( "job1" , "group1" ) //定義name/group
.usingJobData( "name" , "quartz" ) //定義屬性
.build();
//加入這個調度
scheduler.scheduleJob(job,trigger);
//啓動之
scheduler.start();
//運行一段時間後關閉
Thread.sleep(10000);
scheduler.shutdown(true);
}catch(Exception e) {
e.printStackTrace();
}
}
}
至此,代碼結束。在該測試類裏面啓動main方法,eclipse後天就可以看到定時任務的執行效果。
三、說明。
3.1 Quartz框架主要的API接口主要有下面幾個:
1) scheduler- 調度器的主接口
2) Job -- 一個Java類想要成爲一個Job必須實現這個類
3) JobDetail -- 用來定義Job實例
4) Trigger -- 觸發器實例
5)JobBuilder -- 用來定義JobDetail實例
6)TriggerBuilder -- 用來定義觸發器實例
3.2 一個scheduler的生命週期從它被schedulerFactory創u開始被shutdown結束。一旦一個scheduler被創建以後,我們就可以向這個調度器添加、刪除Job和Trigger,列出這個scheduler綁定的Job和Trigger,以及其他操作(比如將某個Trigger掛起)。如果scheduler的start方法不被調用,綁定到他上面的Trigger和Job都不會生效。
3.3 Quartz框架提供了一些“Builder”類,下面我們代碼我們在上一節中見過,這裏我們再拿出來做下示範:
// define the job and tie it to our HelloJob class
JobDetail job = newJob(HelloJob.class)
.withIdentity("myJob", "group1") // name "myJob", group "group1"
.build();
// Trigger the job to run now, and then every 40 seconds
Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();
// Tell quartz to schedule the job using our trigger
sched.scheduleJob(job, trigger);
上面的代碼通過從JobBuilder靜態導入的方法創建一個Job,同樣的,通過從TriggerBuilder導入的靜態方法創建Trigger。
3.4 Quartz框架提供了多種scheduleBuilder類,這些類可以創建不同類型的scheduler。DateBuilder類提供了很多方法能夠很方便的構建特定時間點的時間實例(比如說能夠得到當前時間的下個整點時間點 )。
3.5
當一個Job的觸發器觸發的時候,上面的execute方法會被調用。JobExecutionContext包含了Job的運行時信息 。
JobDetail對象是在被添加到調度器的時候被Quartz客戶端(也就是你的程序)創建的。JobDetail這個對象有很多屬性可以設置,比如說JobDataMap,它可以被用來存儲一個 Job的狀態信息。JobDataMap是我們定義一個Job時最重要的東西,在後面的章節中我們會重點討論。
觸發器對象用來觸發一個Job的執行。當你想要調度一個Job的時候,你需要實例化一個觸發器並將它的觸發時間調整到你希望的時間點。觸發器也可以有和他們關聯的JobDataMap(當多個觸發器會觸發同一個Job,但是需要向這個Job傳遞不同的data時特別有用)。Quartz框架有很多種觸發器,最常用的是SimpleTrigger和CronTrigg。
3.6 Job和觸發器分開設計,有很多好處。比如,Job可以獨立於Trigger之外存儲在scheduler中,多個觸發器可以被綁定到一個Job。這種鬆耦合的另外一種好處是:當一個Trigger過期之後,可以重新複用和這個Trigger綁定的Job。