Quartz介紹和使用
什么是Quartz,干什么的?
Quartz框架是一個全功能、開源的任務調度服務,可以集成幾乎任何的java應用程序—從小的單片機系統到大型的電子商務系統。Quartz可以執行上千上萬的任務調度。
Quartz用來:
如網頁游戲中掛機自動修煉如8個小時,人物相關數值進行成長,當使用某道具后,時間減少到4個小時,人物對應獲得成長值.這其中就涉及到了Scheduler的操作,定時對人物進行更新屬性操作,更改定時任務執行時間。
業務如每天凌晨2點觸發數據同步、發送Email、斷線等操作。
核心概念
Quartz核心的概念:scheduler任務調度、Job任務、Trigger觸發器、JobDetail任務細節。
scheduler任務調度:
是最核心的概念,需要把JobDetail和Trigger注冊到scheduler中,才可以執行。
// 6、工廠模式,組裝各個組件<JOB,Trigger> sched.scheduleJob(job, trigger);
Job任務:
其實Job是接口,其中只有一個execute方法:

package quartz; import org.apache.log4j.Logger; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Date; /** * Created by drubber on 2017/11/23. * @author drubber */ public class HelloJob implements Job { private Logger logger = Logger.getLogger(HelloJob.class); public HelloJob() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDetail detail = context.getJobDetail(); String name = detail.getJobDataMap().getString("name"); logger.info("say hello to " + name + " at " + new Date()); System.out.println("---------------end----------------"); } }
我們只需要 implements 此接口,重寫 execute(*) 方法。
Trigger觸發器:
執行任務的規則;比如每天,每小時等。
一般情況使用SimpleTrigger,和CronTrigger,這些觸發器實現了Trigger接口。或者 ScheduleBuilder 子類 SimpleScheduleBuilder和CronScheduleBuilder。
對於簡單的時間來說,比如每天執行幾次,使用SimpleTrigger。
對於復雜的時間表達式來說,比如每個月15日上午幾點幾分,使用CronTrigger以及CromExpression 類。
JobDetail:
任務細節,Quartz執行Job時,需要新建個Job實例,但是不能直接操作Job類,所以通過JobDetail來獲取Job的名稱、描述信息。
Quartz使用
1、導入Quartz所需的兩個jar包

<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.1</version> </dependency>
2、創建我們自己的Job類實例,進行簡單的輸出

package quartz; import org.apache.log4j.Logger; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Date; /** * Created by drubber on 2017/11/23. * @author drubber */ public class HelloJob implements Job { private Logger logger = Logger.getLogger(HelloJob.class); public HelloJob() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDetail detail = context.getJobDetail(); String name = detail.getJobDataMap().getString("name"); logger.info("say hello to " + name + " at " + new Date()); System.out.println("---------------end----------------"); } }

package quartz; import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Test; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; import org.springframework.util.Log4jConfigurer; import java.io.FileNotFoundException; import java.util.Date; import static org.quartz.DateBuilder.evenMinuteDate; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.TriggerBuilder.newTrigger; /** * 此Demo將演示如何啟動和關閉Quartz調度器,以及如何運作 * Created by drubber on 2017/11/23. * * @author drubber */ public class QuartzExample { private Logger log = Logger.getLogger(QuartzExample.class); public QuartzExample() { } @Before public void initLog4j(){ try { Log4jConfigurer.initLogging("classpath:config/log4j.properties"); } catch (FileNotFoundException e) { System.err.println("Cannot Initialize Log4j !!!!!!"); } } @Test public void run() throws Exception { log.info("------- Initializing ----------------------"); // 1、工廠模式 構建Scheduler的Factory\ // 2、其中StdSchedulerFactory 為Quartz默認的Factory,默認加載quartz.properties,開發者亦可自行實現自己的Factory;Job、Trigger等組件 SchedulerFactory sf = new StdSchedulerFactory(); // 2、通過SchedulerFactory獲得Scheduler對象 Scheduler sched = sf.getScheduler(); log.info("------- Initializing Complete -----------------"); // 3、org.quartz.DateBuilder.evenMinuteDate <下一分鍾> -- 通過DateBuilder構建Date //Date runTime = evenMinuteDate(new Date()); Date runTime = new Date(); log.info("------- Scheduling Job -------------------"); // 4、org.quartz.JobBuilder.newJob --通過JobBuilder構建Job JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build(); //設置參數 job.getJobDataMap().put("name","drubber_ceshi"); // 5、通過TriggerBuilder進行構建 //Trigger trigger = getTrigger(runTime,"simple"); Trigger trigger = getTrigger(runTime,"cron"); // 6、工廠模式,組裝各個組件<JOB,Trigger> sched.scheduleJob(job, trigger); // [group1.job1] will run at: log.info(job.getKey() + " will run at: " + runTime); //7、start sched.start(); log.info("------------Started Scheduler-----------"); Thread.sleep(10 * 1000L); log.info("-------wait 10 seconds ------"); // shut down the scheduler log.info("------- Shutting Down ---------------------"); // 8、通過Scheduler銷毀內置的Trigger和Job sched.shutdown(true); log.info("------- Shutdown Complete -----------------"); } private Trigger getTrigger(Date runTime, String type) { Trigger trigger = null; if (type.equals("simple")) { //使用simpleTrigger 每秒執行一次 一直循環 只到關閉sched trigger = newTrigger().withIdentity("trigger1", "group1") .startAt(runTime) .withSchedule(simpleSchedule() .withIntervalInSeconds(1) .repeatForever()) .build(); } else if (type.equals("cron")) { //使用CronTrigger 每2秒執行一次 一直循環 只到關閉sched trigger = newTrigger().withIdentity("trigger1", "group1") .startAt(runTime) .withSchedule(cronSchedule("*/2 * * * * ? *")) .build(); }else{ //TODO } return trigger; } }
這里我們使用 SimpleTrigger 和 CronTrigger 兩個值方式執行調度。 Cron Expression表達式可以查看 http://www.cnblogs.com/drubber/p/5845014.html 或者查看源碼
Quartz 的調用方式
1、創建調度工廠(); //工廠模式
2、根據工廠取得調度器實例(); //工廠模式
3、Builder模式構建子組件<Job,Trigger> // builder模式, 如JobBuilder、TriggerBuilder、DateBuilder
4、通過調度器組裝子組件 調度器.組裝<子組件1,子組件2...> //工廠模式
5、調度器.start(); //工廠模式