Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. 來源: http://www.quartz-scheduler.org/
1.Job 表示一個工做,要執行的具體內容。此接口中只有一個方法,以下:git
void execute(JobExecutionContext context)
2.JobDetail Quartz 每次調度 Job 時,都從新建立一個 Job 實例,因此它不直接接受一個 Job 的實例,相反它接收一個 Job 實現類(JobDetail,描述 Job 的實現類及其餘相關的靜態信息,如 Job 名字、描述、關聯監聽器等信息),以便運行時經過 newInstance() 的反射機制實例化 Job。github
3.Trigger 表明一個調度參數的配置,何時去調。即觸發的時機spring
4.Scheduler 表明一個調度容器,一個調度容器中能夠註冊多個 JobDetail 和 Trigger。當 Trigger 與 JobDetail 組合,就能夠被 Scheduler 容器調度了。app
配置pom.xmlide
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
簡單示例spring-boot
使用 Quartz 定時輸出 Hello Worldui
首先定義一個 Job 須要繼承 QuartzJobBean,示例中 Job 定義一個變量 Name,用於在定時執行的時候傳入。this
public class SampleJob extends QuartzJobBean { private String name; public void setName(String name) { this.name = name; } [@Override](https://my.oschina.net/u/1162528) protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println(String.format("Hello %s!", this.name)); } }
接下來構建 JobDetail,而且構建時傳入 name 屬性的值,構建 JobTrigger 和 scheduleBuilder,最後使用 Scheduler 啓動定時任務。.net
@Configuration public class SampleScheduler { [@Bean](https://my.oschina.net/bean) public JobDetail sampleJobDetail() { return JobBuilder.newJob(SampleJob.class).withIdentity("sampleJob") .usingJobData("name", "World").storeDurably().build(); } [@Bean](https://my.oschina.net/bean) public Trigger sampleJobTrigger() { SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(2).repeatForever(); return TriggerBuilder.newTrigger().forJob(sampleJobDetail()) .withIdentity("sampleTrigger").withSchedule(scheduleBuilder).build(); } }
啓動項目後每隔兩秒輸出:Hello World!code
Hello World! Hello World! Hello World! ...
CronSchedule 示例
CronSchedule 能夠設置更靈活的使用方式,定時設置能夠參考 cron 表達式。
首先定義兩個 Job:
public class ScheduledJob implements Job { [@Override](https://my.oschina.net/u/1162528) public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("schedule job1 is running ..."); } } public class ScheduledJob2 implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("schedule job2 is running ..."); } }
按照使用 Quartz 的邏輯,構建 jobDetail、CronTrigger,最後使用 scheduler 關聯 jobDetail 和 CronTrigger。scheduleJob1 設置每間隔 6 秒執行一次。
@Component public class CronSchedulerJob { @Autowired private SchedulerFactoryBean schedulerFactoryBean; public void scheduleJobs() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduleJob1(scheduler); scheduleJob2(scheduler); } private void scheduleJob1(Scheduler scheduler) throws SchedulerException{ JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class) .withIdentity("job1", "group1").build(); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/6 * * * * ?"); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") .withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); } private void scheduleJob2(Scheduler scheduler) throws SchedulerException{ JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class) .withIdentity("job2", "group2").build(); CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/12 * * * * ?"); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group2") .withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); } }
CronScheduleBuilder.cronSchedule("0/6 * * * * ?"),按照 cron 表達式設置定時任務的執行週期。
scheduleJob 2 的內容和 scheduleJob 1 基本一致,時間設置爲間隔 12 秒執行一次。
這裏使用 scheduler 啓動兩個定時任務。
public void scheduleJobs() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduleJob1(scheduler); scheduleJob2(scheduler); }
什麼時候觸發定時任務
兩種方案來觸發 CronSchedule 定時任務,一種是啓動時調用 scheduleJobs() 來啓動定時任務,另一種方案使用 Spring Boot 自帶的 Scheduled 在特定時間觸發啓動。
第一種方案,啓動時觸發定時任務: ( 定時一個 Runner,繼承 CommandLineRunner 並從新 run 方法,在 run 方法中調用 scheduleJobs() 來啓動定時任務。)
@Component public class MyStartupRunner implements CommandLineRunner { @Autowired public CronSchedulerJob scheduleJobs; @Override public void run(String... args) throws Exception { scheduleJobs.scheduleJobs(); System.out.println(">>>>>>>>>>>>>>>定時任務開始執行<<<<<<<<<<<<<"); } }
第二種方案,特定時間啓動定時任務:
@Configuration @EnableScheduling @Component public class SchedulerListener { @Autowired public CronSchedulerJob scheduleJobs; @Scheduled(cron="0 30 11 25 11 ?") public void schedule() throws SchedulerException { scheduleJobs.scheduleJobs(); } }
通常狀況下,建議使用第一種方案來啓動定時任務;第二種方案設置固定日期時,須要考慮重複啓動定時任務的狀況,重複啓動定時任務會報錯。
注意,兩種啓動方案,在項目中選擇一種使用便可,不然會致使重複啓動定時任務而報錯。
若是須要在項目中執行大量的批任務處理時,能夠採用 Quartz 來解決,Spring Boot 2.0 中提供了對 Quartz 的支持,讓咱們在項目使用的過程當中更加的靈活簡潔。 gitHub地址: https://github.com/Grit-tan/quartzDemo