kagamihogeの日記

kagamihogeの日記です。

Spring Batch 4.1.x - Reference Documentation - What’s New in Spring Batch 4.1のテキトー翻訳

https://docs.spring.io/spring-batch/4.1.x/reference/html/whatsnew.html#whatsNew

https://qiita.com/kagamihoge/items/12fbbc2eac5b8a5ac1e0 俺の訳一覧リスト

1. What’s New in Spring Batch 4.1

Spring Batch 4.1 releaseは以下の新機能があります。

@SpringBatchTestアノテーション

Spring Batchにはバッチコンポーネントテスト用のユーティリティクラス(JobLauncherTestUtilsJobRepositoryTestUtils)とtest execution listeners(StepScopeTestExecutionListenerJobScopeTestExecutionListener)があります。しかし、これらユーティリティを使用するには、明示的なbean設定が必要です。今回リリースで導入する@SpringBatchTestは自動的にユーティリティのbeanとリスナをテストコンテキストに追加してautowiringで利用可能にします。

@RunWith(SpringRunner.class)
@SpringBatchTest
@ContextConfiguration(classes = {JobConfiguration.class})
public class JobTest {

   @Autowired
   private JobLauncherTestUtils jobLauncherTestUtils;

   @Autowired
   private JobRepositoryTestUtils jobRepositoryTestUtils;


   @Before
   public void clearMetadata() {
      jobRepositoryTestUtils.removeJobExecutions();
   }

   @Test
   public void testJob() throws Exception {
      // given
      JobParameters jobParameters =
            jobLauncherTestUtils.getUniqueJobParameters();

      // when
      JobExecution jobExecution =
            jobLauncherTestUtils.launchJob(jobParameters);

      // then
      Assert.assertEquals(ExitStatus.COMPLETED,
                          jobExecution.getExitStatus());
   }

}

このアノテーションについては、Unit Testingを参照してください。

1.2. @EnableBatchIntegration Annotation

remote chunking jobの設定にはいくつかのbean定義が必要です。

  • メッセージングミドルウェア(JMS, AMQPなど)からコネクションを得るためのコネクションファクトリ
  • MessagingTemplate マスタからワーカーにリクエストを送信してその戻りの処理
  • メッセージングミドルウェアからメッセージを得るSpring Integrationの入出力チャネル
  • 処理と書き込みをするワーカーにデータのchunkを送信する、マスター側のitem writer(ChunkMessageChannelItemWriter
  • マスターからデータを受信する、ワーカー側のメッセージリスナー(ChunkProcessorChunkHandler

これは一見するだけで設定が面倒なのが分かります。今回リリースではAPIに加えて設定を簡易化するための@EnableBatchIntegrationも追加しています。以下はこのアノテーションAPIの使用例です。

@Configuration
@EnableBatchProcessing
@EnableBatchIntegration
public class RemoteChunkingAppConfig {

   @Autowired
   private RemoteChunkingMasterStepBuilderFactory masterStepBuilderFactory;

   @Autowired
   private RemoteChunkingWorkerBuilder workerBuilder;

   @Bean
   public TaskletStep masterStep() {
         return this.masterStepBuilderFactory
                         .get("masterStep")
                         .chunk(100)
                         .reader(itemReader())
                         .outputChannel(outgoingRequestsToWorkers())
                         .inputChannel(incomingRepliesFromWorkers())
                         .build();
   }

   @Bean
   public IntegrationFlow worker() {
         return this.workerBuilder
                         .itemProcessor(itemProcessor())
                         .itemWriter(itemWriter())
                         .inputChannel(incomingRequestsFromMaster())
                         .outputChannel(outgoingRepliesToMaster())
                         .build();
   }

   // Middleware beans setup omitted
}

このアノテーションは基盤となるbean設定の負荷を軽減します。ワーカー側のSpring Integration flowと同じように、マスターのstepを設定します。remote chunkingのこれら新規APIを使用するサンプルはsamples moduleで、詳細はSpring Batch Integrationにあります。

remote chunking設定の簡易化に加えて、今回のバージョンはremote partitioningのセットアップを簡易化するAPIRemotePartitioningMasterStepBuilderRemotePartitioningWorkerStepBuilder、も導入しています。以下例のように@EnableBatchIntegrationを付与することで、これらのbeanをautowiredできます。

@Configuration
@EnableBatchProcessing
@EnableBatchIntegration
public class RemotePartitioningAppConfig {

   @Autowired
   private RemotePartitioningMasterStepBuilderFactory masterStepBuilderFactory;

   @Autowired
   private RemotePartitioningWorkerStepBuilderFactory workerStepBuilderFactory;

   @Bean
   public Step masterStep() {
            return this.masterStepBuilderFactory
               .get("masterStep")
               .partitioner("workerStep", partitioner())
               .gridSize(10)
               .outputChannel(outgoingRequestsToWorkers())
               .inputChannel(incomingRepliesFromWorkers())
               .build();
   }

   @Bean
   public Step workerStep() {
            return this.workerStepBuilderFactory
               .get("workerStep")
               .inputChannel(incomingRequestsFromMaster())
               .outputChannel(outgoingRepliesToMaster())
               .chunk(100)
               .reader(itemReader())
               .processor(itemProcessor())
               .writer(itemWriter())
               .build();
   }

   // Middleware beans setup omitted
}

この新規APIの詳細はSpring Batch Integrationを参照してください。

1.3. JSON support

Spring Batch 4.1はJSONフォーマットをサポートします。今回リリースは以下フォーマットのJSONを読み込むitem readerを追加しました。

[
  {
    "isin": "123",
    "quantity": 1,
    "price": 1.2,
    "customer": "foo"
  },
  {
    "isin": "456",
    "quantity": 2,
    "price": 1.4,
    "customer": "bar"
  }
]

XML用のStaxEventItemReaderの類似機能で、JsonItemReaderはchunkのJSONオブジェクトを読み込むのにストリーミングAPIを使用します。Spring Batchは以下2つのライブラリをサポートします。

上記以外のライブラリを使う場合、JsonObjectReaderインタフェースを実装してください。

また、JSONデータの書き込みにはJsonFileItemWriterがあります。JSONサポートの詳細については、ItemReaders and ItemWritersを参照してください。

1.4. Bean Validation API support

今回リリースではValidatingItemProcessor実装のBeanValidatingItemProcessorを提供しており、これはBean Validation API (JSR-303)アノテーションでitemをvalidateします。例えば、以下のPersonがあるとします。

class Person {

    @NotEmpty
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

BeanValidatingItemProcessorのbeanを作成してchunk stepにprocessorとしてアプリケーションコンテキストに登録してitemをvalidateします。

@Bean
public BeanValidatingItemProcessor<Person> beanValidatingItemProcessor() throws Exception {
        BeanValidatingItemProcessor<Person> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>();
        beanValidatingItemProcessor.setFilter(true);

        return beanValidatingItemProcessor;
}

1.5. JSR-305 support

今回リリースはJSR-305向けの機能を追加しています。Spring FrameworkNull-safetyアノテーションを使用し、Spring Batchのpublic APIに追加します。

これらアノテーションはSpring Batch API使用時にnull-safetyを強制するだけでなく、IDEにnullに関する有用な情報を提供するのにも使えます。たとえば、ItemReaderインタフェースを実装するとして、JSR-305アノテーションをサポートするIDEは以下を生成可能になります。

public class MyItemReader implements ItemReader<String> {

        @Nullable
        public String read() throws Exception {
                return null;
        }

}

readメソッドの@Nullableアノテーションnullを返す可能性があるという契約を明示しています。Javadocの記述である、readメソッドはデータソース読み込み完了時にnullを返す、をアノテーションにより強制しています。

1.6. FlatFileItemWriterBuilder enhancements

今回リリースの小規模変更にフラットファイル書き込み設定簡易化があります。具体的には、デリミタと固定幅ファイルの簡易化です。以下は変更前と後の例です。

// Before
@Bean
public FlatFileItemWriter<Item> itemWriter(Resource resource) {
        BeanWrapperFieldExtractor<Item> fieldExtractor =
            new BeanWrapperFieldExtractor<Item>();
        fieldExtractor.setNames(new String[] {"field1", "field2", "field3"});
        fieldExtractor.afterPropertiesSet();

        DelimitedLineAggregator aggregator = new DelimitedLineAggregator();
        aggregator.setFieldExtractor(fieldExtractor);
        aggregator.setDelimiter(";");

        return new FlatFileItemWriterBuilder<Item>()
                        .name("itemWriter")
                        .resource(resource)
                        .lineAggregator(aggregator)
                        .build();
}

// After
@Bean
public FlatFileItemWriter<Item> itemWriter(Resource resource) {
        return new FlatFileItemWriterBuilder<Item>()
                        .name("itemWriter")
                        .resource(resource)
                        .delimited()
                        .delimiter(";")
                        .names(new String[] {"field1", "field2", "field3"})
                        .build();
}