SpringBoot集成Quartz

SpringBoot集成Quartz

什麼是Quartz

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/

Quartz 的優勢

  • 豐富的 Job 操做 API;
  • 支持多種配置
  • Spring Boot 無縫集成;
  • 支持持久化;
  • 支持集羣
  • 開源

Quartz的核心概念

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

相關文章
相關標籤/搜索