業務でSpringBatchを使用する機会があったので、その備忘録。
顧客の環境がJDK8を使用していたのでSpringBatchのバージョンは4を使用することになり、今後参考になるかはわからないが。
メタテーブルが必要
SpringBatchを実行する際、RDBにメタテーブルを用意する必要がある。実行履歴などを記録しているものだ。
テーブル作成のスクリプト自体はspring-batch-core
というjarファイルの中に用意されている。
この時はMySQLを使用した。
- jarファイル内のスクリプトファイルの場所
/org/springframework/batch/core/schema-mysql.sql
プロパティファイル
application.properties
に以下の設定を追加して使用した。
-
spring.batch.jdbc.initialize-schema=never
メタテーブルをバッチの起動ごとに毎回作成し直すかの設定。neverはし直さない。 -
spring.datasource.url=jdbc:mysql://host/schema
spring.datasource.username=user
spring.datasource.password=pass
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
MySQLの接続設定 -
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
キャメルケースを勝手にスネークケースに読み替えてしまうため、読み替えないために設定をしている。
クラス
ここでは便宜上とHelloWorldとする
HelloWorldBatchApplication
SpringBootでお約束のApplication
@SpringBootApplication
@EnableScheduling
public class HelloWorldBatchApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldBatchApplication.class, args);
}
}
-
@EnableScheduling
スケジュールを有効にするアノテーション
HelloWorldBatchConfig
実行するジョブとそのステップを定義する。
@Configuration
@EnableBatchProcessing
public class HelloWorldBatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private HelloWorldTasklet helloWorldTasklet;
/**
* HelloWorldジョブ
* @param helloWorldStep
* @return
*/
@Bean(name="helloWorldJob")
public Job helloWorldJob(Step helloWorldStep) {
return jobBuilderFactory.get("helloWorldJob") //Job名を指定
.incrementer(new RunIdIncrementer())
.flow(helloWorldStep) //実行するStepを指定
.end()
.build();
}
/**
* HelloWorldのステップ
* @param helloWorldStep
* @return
*/
@Bean
public Step helloWorldStep() {
return stepBuilderFactory.get("helloWorldStep") //Step名を指定
.tasklet(helloWorldTasklet) //実行するTaskletを指定
.build();
}
}
- JOBを定義するメソッド内にてincrementerで実行IDをインクリメントしている。これをしないと一つのJOBで同一の実行IDとなるので、一度実行した同じJOBを再度実行しても、すでに実行済みとなって処理が終了してしまうことが起きた。
ScheduledJobLauncher
ジョブのスケジュールを管理するクラス
@Component
public class ScheduledJobLauncher {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job helloWorldJob;
@Scheduled(cron = "*/5 * * * * *")
public void launchJob() throws Exception {
JobParameters jobParameters = new JobParametersBuilder();
jobLauncher.run(helloWorldJob, jobParameters);
}
- SpringBatchでは秒までの設定が可能であるため、cron形式でスケジュールを設定する場合Linuxの5個ではなく6個の指定箇所がある。左端が秒。この例では5秒毎に実行される
-
HelloWorldBatchConfig
のBeanアノテーションで定義されたhelloWorldJob
を指定している - もしHelloWorldBatchConfigで.incrementer(new RunIdIncrementer())を使わずに実行履歴をユニークにしたい場合は、以下のようにパラメータを指定してあげると、IDのインクリメントの代わりにTimestampがIDとして使用される
JobParameters jobParameters = new JobParametersBuilder()
.addLong("timestamp", System.currentTimeMillis())
.toJobParameters();
HelloWorldTasklet
ステップの中身のクラス。実際のバッチの処理はTaskletに書く。
@Component
@StepScope
public class HelloWorldTasklet implements Tasklet {
/**
* HelloWorldジョブのtasklet
*/
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("Hello, World!");
return RepeatStatus.FINISHED;
}
}
その他
ここでは記載しなかったが、メタテーブルにデータがどんどん追加されていってしまうので、定期的にレコードを削除するバッチも作成した(参照記事)
以上