このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Batch ドキュメント 6.0.6 を使用してください! |
既存のサービスと API の再利用
バッチシステムは、他のアプリケーションスタイルと組み合わせて使用されることがよくあります。最も一般的なのはオンラインシステムですが、各アプリケーションスタイルが使用する必要なバルクデータを移動することで、統合やシッククライアントアプリケーションをサポートすることもあります。そのため、多くのユーザーがバッチジョブ内で既存の DAO、サービス、その他の API を再利用したいと考えるのはよくあることです。Spring コンテナー自体は、必要なクラスを注入できるようにすることで、これを比較的容易にします。ただし、既存のサービスまたは API が、別の Spring Batch クラスの依存関係を満たすため、またはステップのメインの ItemReader であるため、ItemReader または ItemWriter として動作する必要がある場合もあります。
既存のサービスの再利用
ラップが必要なサービスごとにアダプタークラスを作成するのは非常に簡単ですが、これはよくある問題であるため、Spring Batch は ItemReaderAdapter と ItemWriterAdapter という実装を提供しています。どちらのクラスも、デリゲートパターンを呼び出すことで標準の Spring メソッドを実装しており、セットアップも非常に簡単です。
Java
XML
次の Java の例では、ItemReaderAdapter を使用しています。
@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 を使用しています。
<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" /> 注意すべき重要な点の 1 つは、targetMethod の契約は read の契約と同じでなければならないということです。使い果たされると、null が返されます。それ以外の場合は、Object を返します。それ以外の場合は、ItemWriter の実装に応じて、フレームワークが処理をいつ終了するかを認識できず、無限ループまたは誤った失敗が発生します。
Java
XML
次の Java の例では、ItemWriterAdapter を使用しています。
@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 を使用しています。
<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" />既存 API の再利用
サービス以外にも、Java Iterator (または Iterable)を介してデータを公開する既存の API を、専用の ItemReader を作成することなく再利用したいというニーズもよくあります。Spring Batch はまさにこの目的のために IteratorItemReader を提供します。IteratorItemReader は、任意の Iterator または Iterable を ItemReader 契約に適合させます。
良い例として、Spring Data Commons 3.1 で導入されたスクロール機能が挙げられます。これは、オフセットベースまたはキーセットベースのスクロールを使用して、リポジトリから返される連続する Window インスタンスを反復処理するための WindowIterator を公開します。
Java
XML
以下の Java の例は、専用のリーダー実装を必要とせずに、Spring Data リポジトリから取得した WindowIterator を ItemReader として再利用する方法を示しています。
interface UserRepository extends Repository<User, Long> {
Window<User> findFirst10ByLastnameOrderByFirstname(String lastname, KeysetScrollPosition position);
}
@Bean
public ItemReader<User> itemReader(UserRepository userRepository) {
WindowIterator<User> users = WindowIterator
.of(position -> userRepository.findFirst10ByLastnameOrderByFirstname("Doe", position))
.startingAt(ScrollPosition.keyset());
return new IteratorItemReader<>(users);
}WindowIterator の構築にはラムダ式が必要なため、<bean> 定義として直接表現することはできません。代わりに、構築ロジックをファクトリメソッドに抽出し、XML から参照することができます。以下にその例を示します。
public class UserItemReaderFactory {
public static ItemReader<User> createItemReader(UserRepository userRepository) {
WindowIterator<User> users = WindowIterator
.of(position -> userRepository.findFirst10ByLastnameOrderByFirstname("Doe", position))
.startingAt(ScrollPosition.keyset());
return new IteratorItemReader<>(users);
}
}<bean id="itemReader" class="org.springframework.batch.infrastructure.item.sample.UserItemReaderFactory"
factory-method="createItemReader">
<constructor-arg ref="userRepository" />
</bean> このパターンは Spring Data のスクロール API に特有のものではありません。Iterator または Iterable を公開する API であれば、同様の方法で ItemReader にも適用できます。