繼承自父 `步驟`
如果一組 `步驟` 共享相似的配置,那麼定義一個“父” `步驟`,具體的 `步驟` 可以從其繼承屬性,可能會有所幫助。類似於 Java 中的類繼承,“子” `步驟` 將其元素和屬性與父步驟結合。子步驟也會覆蓋父步驟中的任何設定。
在下面的示例中,`步驟` `concreteStep1` 繼承自 `parentStep`。它被例項化時使用了 `itemReader`、`itemProcessor`、`itemWriter`、`startLimit=5` 和 `allowStartIfComplete=true`。此外,`concreteStep1` `步驟` 覆蓋了 `commitInterval`,使其為 `5`,如下例所示:
<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 元素內的步驟上仍然是必需的。這有兩個原因:
-
在持久化 `StepExecution` 時,`id` 被用作步驟名稱。如果在同一個 Job 中的多個步驟中引用了相同的獨立步驟,則會發生錯誤。
-
建立作業流時,如本章後面所述,`next` 屬性應指向流程中的步驟,而不是獨立的步驟。
抽象 `步驟`
有時,可能需要定義一個不是完整的 `步驟` 配置的父 `步驟`。例如,如果 `reader`、`writer` 和 `tasklet` 屬性在 `步驟` 配置中被省略,則初始化將失敗。如果必須定義一個不包含這些屬性中一個或多個的父步驟,則應使用 `abstract` 屬性。一個 `abstract` `步驟` 只能被繼承,不能被例項化。
在下面的示例中,如果 `步驟` (abstractParentStep
) 沒有被宣告為抽象的,它將不會被例項化。`步驟` (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>
合併列表
`步驟` 上的一些可配置元素是列表,例如 <listeners/>
元素。如果父 `步驟` 和子 `步驟` 都聲明瞭 <listeners/>
元素,子列表會覆蓋父列表。為了允許子步驟向父步驟定義的列表中新增額外的監聽器,每個列表元素都有一個 merge
屬性。如果元素指定了 merge="true"
,那麼子列表將與父列表合併,而不是覆蓋它。
在下面的示例中,`步驟` "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>