Spring Batch 4.1 正式发布 (GA)!

发布版本 | Mahmoud Ben Hassine | 2018年10月29日 | ...

我很高兴地宣布 Spring Batch 4.1.0.RELEASE 现已可用。

Spring Batch 4.1 GA 中的新特性

此版本新增了以下特性

  • 新增 @SpringBatchTest 注解,简化批处理组件的测试
  • 新增 @EnableBatchIntegration 注解,简化远程分块 (chunking) 和分区 (partitioning) 配置
  • 支持读取和写入 JSON 格式的数据
  • 支持使用 Bean Validation API 验证项目
  • 支持 JSR-305 注解
  • 增强了 FlatFileItemWriterBuilder API

@SpringBatchTest 注解

Spring Batch 提供了一些好用的工具类(例如 JobLauncherTestUtilsJobRepositoryTestUtils)以及测试执行监听器(StepScopeTestExecutionListenerJobScopeTestExecutionListener)用于测试批处理组件。然而,为了使用这些工具,您必须显式配置它们。此版本引入了一个名为 @SpringBatchTest 的新注解,它可以自动将工具 Bean 和监听器添加到测试上下文并使其可用于自动注入,如下例所示

@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());
   }

}

@EnableBatchIntegration 注解

设置远程分块作业需要定义一些 Bean

  • 连接工厂,用于从消息中间件(JMS、AMQP 等)获取连接
  • MessagingTemplate,用于从主节点向工作节点发送请求并返回
  • Spring Integration 的输入通道和输出通道,用于从消息中间件获取消息
  • 主节点上的特殊项目写入器(ChunkMessageChannelItemWriter),知道如何将数据块发送到工作节点进行处理和写入
  • 工作节点上的消息监听器(ChunkProcessorChunkHandler),用于接收来自主节点的数据

乍一看,这可能有点令人望而生畏。此版本引入了一个名为 @EnableBatchIntegration 的新注解以及新的 API(RemoteChunkingMasterStepBuilderRemoteChunkingWorkerBuilder)来简化配置。以下示例展示了如何使用新的注解和 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 流。

就像远程分块配置的简化一样,此版本也引入了新的 API 来简化远程分区设置:RemotePartitioningMasterStepBuilderRemotePartitioningWorkerStepBuilder。如果存在 @EnableBatchIntegration,您可以在配置类中自动注入它们,如下例所示

@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
}

JSON 支持

此版本引入了一个新的项目读取器(JsonItemReader),它可以读取以下格式的 JSON 资源

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

与 XML 的 StaxEventItemReader 类似,新的 JsonItemReader 使用流式 API 分块读取 JSON 对象。Spring Batch 支持两个库

要添加其他实现,您可以实现 JsonObjectReader 接口。通过 JsonFileItemWriter 也支持写入 JSON 数据。

Bean Validation API 支持

此版本带来了一个新的 ValidatingItemProcessor 实现,名为 BeanValidatingItemProcessor,它允许您验证使用 Bean Validation API (JSR-303) 注解的项目。例如,考虑以下 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 并将其注册为分块步骤中的处理器来验证项目,如下例所示

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

	return beanValidatingItemProcessor;
}

JSR-305 支持

此版本增加了对 JSR-305 注解的支持。它使用了 Spring Framework 的空安全 (Null-safety) 注解,并将其添加到 Spring Batch 的所有公共 API 上。

这些注解不仅在使用 Spring Batch API 时强制执行空安全,还可以被 IDE 用于提供与可空性相关的有用信息。例如,如果用户想要实现 ItemReader 接口,任何支持 JSR-305 注解的 IDE 都应该生成类似于以下内容的代码

public class MyItemReader implements ItemReader<String> {

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

}

read 方法上存在的 @Nullable 注解明确表明该方法的契约允许返回 null。这强化了其 Javadoc 中所说的内容,即当数据源耗尽时,read 方法应该返回 null

FlatFileItemWriterBuilder 增强功能

此版本添加的另一个小特性是简化了平面文件写入的配置。具体来说,这些更新简化了分隔文件和固定宽度文件的配置。以下示例展示了更改前后的对比。

// 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();
}

其他改进

除了所有这些新特性之外,此版本还修复了相当多的 bug,并整合了社区通过 Github 上的 Pull Request 贡献的许多增强功能。我们感谢所有贡献者报告问题、提出功能建议以及贡献代码促成此版本的发布!此版本的完整更新日志可在此处找到。

反馈

您可以使用即将发布的 Spring Boot 2.1 GA 来体验 Spring Batch 4.1 GA。我们期待您在 StackOverflowGitterJIRA 上提供反馈。欢迎在 Twitter 上联系 @michaelminella@benas

Spring Batch 主页 | GitHub 上的源代码 | 参考文档

获取 Spring 电子报

通过 Spring 电子报保持联系

订阅

领先一步

VMware 提供培训和认证,助力您加速前行。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供了对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

近期活动

查看 Spring 社区的所有近期活动。

查看全部