当前版本仍在开发中,尚不被视为稳定版本。最新稳定版请使用 Spring Batch 文档 6.0.2!

复用现有服务

批处理系统通常会与其他应用风格配合使用。最常见的是在线系统,但它也可能通过传递各类应用风格所需的大批量数据, 去支持集成型应用,甚至是厚客户端应用。正因为如此,很多用户都希望在批处理 job 中复用现有 DAO 或其他服务。 Spring 容器本身已经让这件事变得相当容易,因为你可以直接注入任何所需类。不过,在某些场景下,现有服务需要充当 ItemReaderItemWriter,可能是为了满足另一个 Spring Batch 类的依赖,也可能因为它本来就是某个 step 的主要 ItemReader。虽然为每个需要包装的服务手写一个适配器类并不难,但由于这是非常常见的需求,Spring Batch 直接提供了 ItemReaderAdapterItemWriterAdapter 两个实现。它们都通过委托模式来实现标准 Spring 调用方式,而且配置起来也很简单。

  • Java

  • XML

下面的 Java 示例使用了 ItemReaderAdapter

Java Configuration
@Bean
public ItemReaderAdapter itemReader() {
	ItemReaderAdapter reader = new ItemReaderAdapter();

	reader.setTargetObject(fooService());
	reader.setTargetMethod("generateFoo");

	return reader;
}

@Bean
public FooService fooService() {
	return new FooService();
}

下面的 XML 示例使用了 ItemReaderAdapter

XML Configuration
<bean id="itemReader" class="org.springframework.batch.infrastructure.item.adapter.ItemReaderAdapter">
    <property name="targetObject" ref="fooService" />
    <property name="targetMethod" value="generateFoo" />
</bean>

<bean id="fooService" class="org.springframework.batch.infrastructure.item.sample.FooService" />

有一个非常重要的点需要注意:targetMethod 的契约必须与 read 的契约一致。也就是说,数据耗尽时它必须返回 null; 否则就返回一个 Object。如果不遵守这个约定,框架就无法判断处理何时结束,最终可能导致无限循环,或者根据 ItemWriter 的实现方式出现错误失败。

  • Java

  • XML

下面的 Java 示例使用了 ItemWriterAdapter

Java Configuration
@Bean
public ItemWriterAdapter itemWriter() {
	ItemWriterAdapter writer = new ItemWriterAdapter();

	writer.setTargetObject(fooService());
	writer.setTargetMethod("processFoo");

	return writer;
}

@Bean
public FooService fooService() {
	return new FooService();
}

下面的 XML 示例使用了 ItemWriterAdapter

XML Configuration
<bean id="itemWriter" class="org.springframework.batch.infrastructure.item.adapter.ItemWriterAdapter">
    <property name="targetObject" ref="fooService" />
    <property name="targetMethod" value="processFoo" />
</bean>

<bean id="fooService" class="org.springframework.batch.infrastructure.item.sample.FooService" />