Dependency

  1. 建立 Spring Boot project 時於 I/O 分類中選擇 Quartz Scheduler
  2. pom.xml 中加入
    ​​​​<dependency>
    ​​​​    <groupId>org.springframework.boot</groupId>
    ​​​​    <artifactId>spring-boot-starter-quartz</artifactId>
    ​​​​</dependency>
    

Config

Spring Quartz Config

  • 定義 job 儲存方式
    spring.quartz.job-store-type=

    1. memory ( Default )
    2. jdbc
  • 定義 schema initialize 方式
    spring.quartz.jdbc.initialize-schema=

    1. embedded ( Default )
    2. always ( 相當於 hibernate.ddl-auto=create,每次重啟專案時會重新建立 Table )
    3. never

Quartz Config

  • 定義使用的 DB
    spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=
    1. org.quartz.impl.jdbcjobstore.StdJDBCDelegate ( Default, MySQL )
    2. org.quartz.impl.jdbcjobstore.MSSQLDelegate
    3. org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
    4. org.quartz.impl.jdbcjobstore.WebLogicDelegate
    5. org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
    6. org.quartz.impl.jdbcjobstore.oracle.WebLogicOracleDelegate
    7. org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate
    8. org.quartz.impl.jdbcjobstore.CloudscapeDelegate
    9. org.quartz.impl.jdbcjobstore.DB2v6Delegate
    10. org.quartz.impl.jdbcjobstore.DB2v7Delegate
    11. org.quartz.impl.jdbcjobstore.DB2v8Delegate
    12. org.quartz.impl.jdbcjobstore.HSQLDBDelegate
    13. org.quartz.impl.jdbcjobstore.PointbaseDelegate
    14. org.quartz.impl.jdbcjobstore.SybaseDelegate

使用

Spring Quartz 已經針對 Scheduler 做好 Auto-Configured,使用時透過 @Autowired 注入

@Autowired
Scheduler scheduler;

Quartz 主要以三個部分組成

Job

  • 用於定義實質排程要執行的內容,如寄信、CRUD 等。
  • 建立
    1. 建立 Job class 並 extends QuartzJobBean
    2. override executeInternal(JobExecutionContext context) method
      • 若有透過 傳送資料,可使用 JobExecutionContext 接收。
    3. bussiness logic 放在 method 內

2. JobDetail

  • 用於指定使用的 Job,可透過 JobDetail 做命名、分組,並加以存取 ( DB / in Memory )
  • 可使用 setJobData(jobDataMap) Method 透過 JobDataMap Object 傳值到 Job。

3. Trigger

  • 用於定義觸發時機並與 JobDetail 綁定使用,可設定排程執行時段或立刻執行。

Controller

...

@Autowired
Scheduler scheduler;

@GetMapping("/alarm")
public void alarmJobs(
    @RequestParam("start") String startDate,
    @RequestParam("end") String endDate
) {
        try {
            JobDetail jobDetail = JobBuilder
                    .newJob(AlarmJob.class)
                    .storeDurably(false) // JobDetail 是否要持久化 ( 若 false, 對應的 trigger 移除時會一併刪除 )
                    .build();
            Trigger trigger = TriggerBuilder
                    .newTrigger()
                    .startAt(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(startDate))
                    .endAt(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(endDate))
                    // .startNow()
                    .withSchedule(SimpleScheduleBuilder
                            .simpleSchedule() // 或使用 cronSchedule()
                            .withIntervalInSeconds(10)
                            .withRepeatCount(5))
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }
}

Issues

  1. 若當下有多個觸發時間超過設定 startAt() 的 Trigger 時,Job 執行次數似乎會有異常,待確認。

Reference

Spring Boot Document
Quartz config
https://www.796t.com/content/1541907006.html