Spring Bootにジョブスケジューラの『Quartz』を組込み
ジョブ登録と削除用エンドポイントを作成し実行します。
■完成イメージ
+----------+ +-------------+ +------------+
| | | Spring Boot | JDBC | Job |
| Browser |<---------->| + |<---------->| Persistent |
| | port=8080 | Quartz | port=33060 | data |
| | | | | (MySQL) |
+----------+ +-------------+ +------------+
■構築環境
・Windows10 バージョン21H2
・IntelliJ IDEA 2022.1.4(Community Edition)
・OpenJDK Runtime Environment Zulu17.36+17-CA (build 17.0.4.1+1-LTS)
・Spring Boot 2.7.4
・Quartz
・Mysql 5.7.39
1. プロジェクトへQuartzを組込む
build.geadleを編集しJPA, JDBC Driver, Quartzの依存関係を追加。
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-quartz'
runtimeOnly 'mysql:mysql-connector-java'
}
2. Spring Bootアプリケーションのパラメータを設定
エンドポイントの受信ポート及びMysqlとの接続設定を追加。
spring.quartz.jdbc.initialize-schemaをalwaysにする事でQuartzに必要なテーブルを自動作成します。
ただし起動時に毎回初期化が走るため、不必要であればneverに変更してください。
またMySQLユーザにはテーブルを作成する適切なロールが紐づいている必要があります。
server.port=8080
spring.datasource.platform=org.hibernate.dialect.MySQL5Dialect
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://***.***.***.***:33060/データベース名
spring.datasource.username=ユーザ名
spring.datasource.password=パスワード
spring.jpa.open-in-view=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
#QUARTZ CONFIGS
spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=always
3. Quartzの起動とDIコンテナへの登録
Spring Bootの起動時にQuartzも同時に起動しDIコンテナにインスタンスを登録します。
@SpringBootApplication
public class SchedulerApplication {
public static void main(String[] args) {
SpringApplication.run(SchedulerApplication.class, args);
}
@Bean
public Scheduler scheduler(SchedulerFactoryBean factory) throws SchedulerException {
Scheduler scheduler = factory.getScheduler();
scheduler.start();
return scheduler;
}
}
4. パラメータクラス作成
ジョブの引数として渡すパラメータクラスを作成。
シリアライズ(直列化)できるようSerializableをimplementsします。
public class JobParameter implements Serializable {
private static final long serialVersionUID = 1L;
private final String uid;
private final String name;
}
5. ジョブクラスを作成
パラメータとして受け取った名前を標準出力するジョブになります。
public class SimpleJob implements Job {
@Override
public void execute(JobExecutionContext context) {
JobDataMap parameter = context.getJobDetail().getJobDataMap();
JobParameter jobParameter = (JobParameter)parameter.get("parameter");
System.out.println(MessageFormat.format("JobName: {0}",jobParameter.getName()));
}
}
6. エンドポイント作成
登録と削除用のエンドポイントを持つコントローラクラスになります。
@RestController
@RequestMapping("/")
public class SimpleController {
private final Scheduler scheduler;
@Autowired
public SimpleController(Scheduler scheduler) {
this.scheduler = scheduler;
}
@GetMapping("/create")
public ResponseEntity create() throws Exception {
// パラメータ作成
JobParameter jobParameter = new JobParameter("0001", "shigemax");
// ジョブ生成及びパラメータ付与
JobDetail job = JobBuilder.newJob(SimpleJob.class)
.withIdentity("sample_job").build();
job.getJobDataMap().put("parameter", jobParameter);
// トリガー設定(120秒後に発火)
Date afterFiveSeconds = Date.from(LocalDateTime.now().plusSeconds(120)
.atZone(ZoneId.systemDefault()).toInstant());
Trigger trigger = TriggerBuilder.newTrigger()
.startAt(afterFiveSeconds)
.build();
// ジョブ登録
this.scheduler.scheduleJob(job, trigger);
return ResponseEntity.ok().build();
}
@GetMapping("/delete")
public ResponseEntity delete() throws Exception {
// ジョブ名で削除
this.scheduler.deleteJob(new JobKey("sample_job"));
return ResponseEntity.ok().build();
}
}
7. Spring Boot起動
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.4)
8. Quartz用テーブルの確認
mysql> SHOW TABLES;
+--------------------------+
| Tables_in_quartz |
+--------------------------+
| QRTZ_BLOB_TRIGGERS |
| QRTZ_CALENDARS |
| QRTZ_CRON_TRIGGERS |
| QRTZ_FIRED_TRIGGERS |
| QRTZ_JOB_DETAILS |
| QRTZ_LOCKS |
| QRTZ_PAUSED_TRIGGER_GRPS |
| QRTZ_SCHEDULER_STATE |
| QRTZ_SIMPLE_TRIGGERS |
| QRTZ_SIMPROP_TRIGGERS |
| QRTZ_TRIGGERS |
+--------------------------+
9. ジョブの登録
HTTP GETにてhttp://localhost:8080/createにリクエスト。
120秒後に標準出力にてパラメータで引き渡された名前が表示される。
JobClass: class com.example.scheduler.job.SimpleJob
JobName: shigemax
10. MySQLコンテナにbashログイン
HTTP GETにてhttp://localhost:8080/createにリクエスト後、
HTTP GETにてhttp://localhost:8080/deleteにリクエスト。
ジョブが削除された為、ジョブが120秒たっても実行されないことを確認。
参考