从父 Step 继承
Step
如果一组 Steps 共享相似的配置,那么定义一个“父” Step 可能很有帮助,具体的 Steps 可以从中继承属性。类似于 Java 中的类继承,“子” Step 会将其元素和属性与父级的合并。子级还会覆盖父级 Steps 的任何属性。
在以下示例中,Step 的具体实现 concreteStep1 继承自 parentStep。它通过 itemReader、itemProcessor、itemWriter 进行实例化,并设置了 startLimit=5 和 allowStartIfComplete=true。此外,commitInterval 被设置为 5,因为该值被 concreteStep1 这个 Step 覆盖,如下例所示:
<step id="parentStep">
<tasklet allow-start-if-complete="true">
<chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
</tasklet>
</step>
<step id="concreteStep1" parent="parentStep">
<tasklet start-limit="5">
<chunk processor="itemProcessor" commit-interval="5"/>
</tasklet>
</step>
id 属性在 job 元素的 step 中仍然是必需的。这主要有两个原因:
-
id在持久化StepExecution时被用作步骤名称。如果在作业的多个步骤中引用了同一个独立步骤,则会发生错误。 -
在创建作业流程时(如本章后续部分所述),
next属性应指向流程中的步骤,而非独立步骤。
摘要 Step
有时,可能需要定义一个并非完整 Step 配置的父级 Step。例如,如果在 Step 配置中省略了 reader、writer 和 tasklet 属性,初始化就会失败。如果必须定义一个缺少其中某些属性的父级,则应使用 abstract 属性。一个 abstract 的 Step 仅用于被继承,而不会被实例化。
在以下示例中,如果 Step (abstractParentStep) 没有被声明为抽象,它将不会被实例化。Step (concreteStep2) 拥有 itemReader、itemWriter 和 commit-interval=10。
<step id="abstractParentStep" abstract="true">
<tasklet>
<chunk commit-interval="10"/>
</tasklet>
</step>
<step id="concreteStep2" parent="abstractParentStep">
<tasklet>
<chunk reader="itemReader" writer="itemWriter"/>
</tasklet>
</step>
合并列表
Steps 中的某些可配置元素是列表类型,例如 <listeners/> 元素。如果父级和子级 Steps 都声明了 <listeners/> 元素,子级的列表会覆盖父级的列表。为了允许子级向父级定义的列表中添加额外的监听器,每个列表元素都有一个 merge 属性。如果该元素指定了 merge="true",那么子级的列表将与父级的列表合并,而不是覆盖它。
在以下示例中,Step "concreteStep3" 创建时配置了两个监听器:listenerOne 和 listenerTwo:
<step id="listenersParentStep" abstract="true">
<listeners>
<listener ref="listenerOne"/>
</listeners>
</step>
<step id="concreteStep3" parent="listenersParentStep">
<tasklet>
<chunk reader="itemReader" writer="itemWriter" commit-interval="5"/>
</tasklet>
<listeners merge="true">
<listener ref="listenerTwo"/>
</listeners>
</step>