Reusing Existing Services
批处理系统常常与其他应用程序风格结合使用。最常见的是在线系统,但它还可以通过移动每个应用程序风格使用的必要批量数据来支持集成,甚至支持厚客户端应用程序。因此,许多用户希望在他们的批处理作业中重用现有的 DAO 或其他服务。Spring 容器本身通过允许注入任何必要的类从而使得这相当容易。然而,在某些情况下,现有的服务需要作为 ItemReader
或 ItemWriter
,以满足另一个 Spring Batch 类的依赖关系,或者因为它真正是一个步骤的主要 ItemReader
。为每个需要包装的服务编写一个适配器类相当容易,但因为这是一个常见的问题,Spring Batch 提供了实现:ItemReaderAdapter
和 ItemWriterAdapter
。这两类通过调用委托模式来实现标准的 Spring 方法,并且设置起来相当简单。
Batch systems are often used in conjunction with other application styles. The most
common is an online system, but it may also support integration or even a thick client
application by moving necessary bulk data that each application style uses. For this
reason, it is common that many users want to reuse existing DAOs or other services within
their batch jobs. The Spring container itself makes this fairly easy by allowing any
necessary class to be injected. However, there may be cases where the existing service
needs to act as an ItemReader
or ItemWriter
, either to satisfy the dependency of
another Spring Batch class or because it truly is the main ItemReader
for a step. It is
fairly trivial to write an adapter class for each service that needs wrapping, but
because it is such a common concern, Spring Batch provides implementations:
ItemReaderAdapter
and ItemWriterAdapter
. Both classes implement the standard Spring
method by invoking the delegate pattern and are fairly simple to set up.
- Java
-
以下 Java 示例使用了
ItemReaderAdapter
:
The following Java example uses the 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
-
以下 XML 示例使用
ItemReaderAdapter
:
The following XML example uses the ItemReaderAdapter
:
<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
的执行情况,既可能导致无限循环,也可能导致不正确的失败。
One important point to note is that the contract of the targetMethod
must be the same
as the contract for read
: When exhausted, it returns null
. Otherwise, it returns an
Object
. Anything else prevents the framework from knowing when processing should end,
either causing an infinite loop or incorrect failure, depending upon the implementation
of the ItemWriter
.
- Java
-
以下 Java 示例使用
ItemWriterAdapter
:
The following Java example uses the 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
-
以下 XML 示例使用
ItemWriterAdapter
:
The following XML example uses the ItemWriterAdapter
:
<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" />