本記事の対象読者
- SpringBatch 5を新しく学習する人
- 下記書籍の学習途中でつまずいた人
悲惨なミスをなくすSpringBatch入門書: Spring解体新書(バッチ編): 基礎から学べるSpring Batch
本の詳細
初めに
筆者は下記書籍をもとにSpring Batchの学習を進めていましたが、情報が古く、最新のSpring Batch 5(以下V5)には対応していませんでした。V5でこの書籍の学習を進めるうえで、抑えておくべきV4とV5の相違点を共有したいと思います。また新しくV5を学習する人の手助けになれば幸いです。
私の場合は、listenerを勉強しているので、主にlistenerの時の練習時にどうやって最新のバージョン5と合わせるかを記述します。
Hello Worldはlistenerより最初の部分なので、この記事で解決できると思います、私も著者の解決策により、自分の練習がうまくできたので、感謝です。
listenerの修正箇所1:ItemWriterのimplementation
主にwriteメソッドの引数の型はListじゃなくてChunkになったので、変えなきゃ。
package com.example.demo.chunk;
import java.util.List;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemWriter;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@StepScope
@Slf4j
public class HelloWriter implements ItemWriter<String> {
@Override
public void write(Chunk<? extends String> chunk) throws Exception {
List<? extends String> items = chunk.getItems();
log.info("writer: {}", items);
log.info("===========");
}
}
listenerの修正箇所2:BatchConfig
StepBuilderとJobBuilderに変えた。後はアノテーションに@EnableBatchProcessingが廃棄したので削除した。
@Configuration
public class BatchConfig {
@Autowired
private ItemReader<String> reader;
@Autowired
private ItemProcessor<String, String> processor;
@Autowired
private ItemWriter<String> writer;
@Autowired
private JobExecutionListener jobListener;
@Autowired
private StepExecutionListener stepListener;
@Bean
Step chunkStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("HelloChunkStep", jobRepository)
.<String, String>chunk(3, transactionManager)
.reader(reader)
.processor(processor)
.writer(writer)
.listener(stepListener)
.build();
}
@Bean
Job chunkJob (JobRepository jobRepository, PlatformTransactionManager transactionManager, Step chunkStep) throws Exception{
return new JobBuilder("HelloWorldChunkJob", jobRepository)
.incrementer(new RunIdIncrementer())
.start(chunkStep)
.listener(jobListener)
.build();
}
}
全部うまく変えたら、eclipseがエラーがならないはず、後は本の通りにログ出力するはず。
本の通りのログ:
Job: [SimpleJob: [name=HelloWorldChunkJob]] launched with the following parameters: [{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}]
[2m2024-12-30T20:11:55.603+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mc.e.demo.listener.HelloJobListener [0;39m [2m:[0;39m Before Job:JobExecution: id=1, version=1, startTime=2024-12-30T20:11:55.597427700, endTime=null, lastUpdated=2024-12-30T20:11:55.597427700, status=STARTED, exitStatus=exitCode=UNKNOWN;exitDescription=, job=[JobInstance: id=1, version=0, Job=[HelloWorldChunkJob]], jobParameters=[{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}]
[2m2024-12-30T20:11:55.609+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mo.s.batch.core.job.SimpleStepHandler [0;39m [2m:[0;39m Executing step: [HelloChunkStep]
[2m2024-12-30T20:11:55.611+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mc.e.demo.listener.HelloStepListener [0;39m [2m:[0;39m Before Step:StepExecution: id=1, version=1, name=HelloChunkStep, status=STARTED, exitStatus=EXECUTING, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=0, rollbackCount=0, exitDescription=
[2m2024-12-30T20:11:55.616+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloReader [0;39m [2m:[0;39m Read:Hello
[2m2024-12-30T20:11:55.618+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloReader [0;39m [2m:[0;39m Read:World
[2m2024-12-30T20:11:55.618+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloReader [0;39m [2m:[0;39m Read:hoge
[2m2024-12-30T20:11:55.619+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloProcessor [0;39m [2m:[0;39m Processor:Hello★
[2m2024-12-30T20:11:55.619+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloProcessor [0;39m [2m:[0;39m Processor:World★
[2m2024-12-30T20:11:55.620+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloProcessor [0;39m [2m:[0;39m Processor:hoge★
[2m2024-12-30T20:11:55.620+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloWriter [0;39m [2m:[0;39m writer: [Hello★, World★, hoge★]
[2m2024-12-30T20:11:55.620+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloWriter [0;39m [2m:[0;39m ===========
[2m2024-12-30T20:11:55.622+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloReader [0;39m [2m:[0;39m Read:fuga
[2m2024-12-30T20:11:55.622+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloReader [0;39m [2m:[0;39m Read:null
[2m2024-12-30T20:11:55.622+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloProcessor [0;39m [2m:[0;39m Processor:fuga★
[2m2024-12-30T20:11:55.622+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloWriter [0;39m [2m:[0;39m writer: [fuga★]
[2m2024-12-30T20:11:55.622+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mcom.example.demo.chunk.HelloWriter [0;39m [2m:[0;39m ===========
[2m2024-12-30T20:11:55.624+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mo.s.batch.core.step.AbstractStep [0;39m [2m:[0;39m Step: [HelloChunkStep] executed in 13ms
[2m2024-12-30T20:11:55.624+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mc.e.demo.listener.HelloStepListener [0;39m [2m:[0;39m After Step:StepExecution: id=1, version=3, name=HelloChunkStep, status=COMPLETED, exitStatus=COMPLETED, readCount=4, filterCount=0, writeCount=4 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=2, rollbackCount=0, exitDescription=
[2m2024-12-30T20:11:55.627+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mc.e.demo.listener.HelloJobListener [0;39m [2m:[0;39m After Job:JobExecution: id=1, version=1, startTime=2024-12-30T20:11:55.597427700, endTime=2024-12-30T20:11:55.627243300, lastUpdated=2024-12-30T20:11:55.597427700, status=COMPLETED, exitStatus=exitCode=COMPLETED;exitDescription=, job=[JobInstance: id=1, version=0, Job=[HelloWorldChunkJob]], jobParameters=[{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}]
[2m2024-12-30T20:11:55.629+09:00[0;39m [32m INFO[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ restartedMain] [0;39m[36mo.s.b.c.l.s.TaskExecutorJobLauncher [0;39m [2m:[0;39m Job: [SimpleJob: [name=HelloWorldChunkJob]] completed with the following parameters: [{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}] and the following status: [COMPLETED] in 29ms
[2m2024-12-30T20:11:55.635+09:00[0;39m [33m WARN[0;39m [35m20832[0;39m [2m--- [BatchHelloWorldChunk] [ionShutdownHook] [0;39m[36mo.s.b.f.support.DisposableBeanAdapter [0;39m [2m: