重用現有服務

批處理系統通常與其他應用程式風格結合使用。最常見的是線上系統,但它也可以透過移動每種應用程式風格所需的大量資料來支援整合甚至胖客戶端應用程式。因此,許多使用者希望在其批處理 Job 中重用現有的 DAO 或其他服務是很常見的。Spring 容器本身透過允許注入任何必要的類來使這變得相當容易。但是,在某些情況下,現有服務需要充當 `ItemReader` 或 `ItemWriter`,這可能是為了滿足另一個 Spring Batch 類的依賴關係,或者因為它確實是某個 Step 的主要 `ItemReader`。為每個需要包裝的服務編寫一個介面卡類是相當簡單的,但由於這是一個非常常見的問題,Spring Batch 提供了實現:`ItemReaderAdapter` 和 `ItemWriterAdapter`。這兩個類都透過呼叫委派模式(delegate pattern)實現了標準的 Spring 方法,並且設定起來非常簡單。

  • Java

  • XML

以下 Java 示例使用了 `ItemReaderAdapter`

Java 配置
@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 配置
<bean id="itemReader" class="org.springframework.batch.item.adapter.ItemReaderAdapter">
    <property name="targetObject" ref="fooService" />
    <property name="targetMethod" value="generateFoo" />
</bean>

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

需要注意的一個重點是,`targetMethod` 的契約必須與 `read` 的契約相同:當耗盡時,它返回 `null`。否則,它返回一個 `Object`。任何其他返回值都會阻止框架知道何時應該結束處理,這可能導致無限迴圈或不正確的失敗,具體取決於 `ItemWriter` 的實現。

  • Java

  • XML

以下 Java 示例使用了 `ItemWriterAdapter`

Java 配置
@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 配置
<bean id="itemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
    <property name="targetObject" ref="fooService" />
    <property name="targetMethod" value="processFoo" />
</bean>

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