Spring Batch 2.0 新特性概覽

工程技術 | Dave Syer | 2008年10月21日 | ...

在本文中,我們概述了 Spring Batch 2.0 的主要主題,並強調了與 1.x 的變化。新版本的開發工作正在順利進行中,上週釋出了 M2 版本,並且我們獲得了廣泛的關注,所以現在似乎是提供一些指導的好時機。

Spring Batch 2.0 主題

新版本的四個主要主題是

  • Java 5 和 Spring 3.0
  • 非順序執行
  • 可伸縮性
  • 配置:註解和 XML 名稱空間
因此我們將分別介紹這些領域,並描述它們的含義以及這些變化對 Spring Batch 現有使用者的影響。下面有關於已實現功能的更多詳細資訊,這些功能主要集中在第一個類別中,並在其他領域提供了一些支援性功能。

Spring Batch 2.0.0.M2 的專案物理佈局沒有變化(與舊版本下載相同,Java 包的基本佈局也相同)。我們沒有刪除任何功能,但藉此機會修訂了一些 API,對於從 1.x 更新專案的使用者來說,有一些小的變化。Spring Batch 還不夠成熟,而且我們正在新增一些相當大的功能,所以我們決定進行一次主版本變更是一個很好的機會來進行一些清理。我們預計沒有人會遇到升級困難,如果您是現有使用者,本文將幫助您瞭解這些變化。

Java 5 和 Spring 3.0

正如您可能知道的,Spring 3.0 將成為 Spring 首個專門針對 Java 5 的主要版本(更詳細的說明留給 Juergen 和 Arjen 來澄清)。既然 Sun 已經對 JDK 1.4 打上了 "服務生命週期結束" 的標記,這看起來是合適的,而且 Spring 3.0 中有一些我們想要利用的很棒的新功能。

型別安全

Spring Batch 2.0.0.M1 版本的大部分工作是把現有程式碼轉換為 Java 5,儘可能地利用泛型和引數化型別。這為框架的使用者提供了更愉快的程式設計體驗,允許在編譯時進行型別安全檢查,最終降低了使用 Spring Batch 的專案的維護成本。例如,在ItemReader,作為 Spring Batch 中核心介面和使用者擴充套件點之一,我們現在有一個型別安全的read方法

public interface ItemReader<S> {
    S read();
}

這裡需要進一步注意的一點是,舊的(1.x)框架回調函式mark()reset()已從此介面中移除,使其對終端使用者更加友好,並防止對框架何時需要什麼產生誤解。同樣的關注點(即 mark 和 reset)現在在框架提供的Step實現中內部處理。

面向塊的處理

類似的變化,以及一個稍微更徹底的變化,也發生在搭檔ItemWriter介面中,框架使用它來寫入資料


public interface ItemWriter<T> {
    void write(List<? extends T> items);
}

舊的框架回調函式flush()clear()也從此介面中移除,為了彌補這一點,write()方法有了新的簽名。這裡的重點是,我們在框架內部轉向了面向塊的處理正規化。這在批處理框架中實際上比舊的面向項的方法更自然,因為出於效能原因,我們經常需要緩衝和重新整理,而舊的介面使使用者感到不便。現在您可以在write()方法內部完成所有需要的批處理。

Step Factory Bean 變更

面向塊的處理方法的副作用是步驟工廠 bean 實現的改變。舊的SkipLimitStepFactoryBean已重新命名為FaultTolerantStepFactoryBean,並且在大多數常見用例中仍然可以用作舊工廠 bean 的替代品。預設情況下,它建立一個步驟實現,該實現會在回滾時緩衝輸入項,以便新的ItemReaderItemWriter介面能與非事務性輸入源(如檔案)正常工作。對於在回滾後重新提供項的輸入源,客戶端必須在工廠 bean 中設定一個標誌(isReaderTransactional是截至 M2 版本的標誌名稱)-JmsItemReader是框架中唯一相關的 reader,並且使用它的專案不多,所以這不是一個大的改變。

業務處理

一個相關的新功能是,以ItemProcessor:

public interface ItemProcessor<S,T> {
    T process(S item);
}

的形式,出現了一個新成員。在 1.x 中,型別為S的輸入項和型別為T的輸出項之間的轉換必須隱藏在其他參與者之一(通常是ItemWriter)內部。現在我們已經將這個關注點泛化,並在框架中將其置於與其兄弟姐妹ItemReaderItemWriter同等重要的地位。1.x 的使用者可能會認出舊的ItemTransformer介面的痕跡,該介面現已移除。

一個更有用的 Tasklet 介面

許多人在檢視 Spring Batch 1.x 時曾問過:“如果我的業務邏輯不是讀取和寫入怎麼辦?” 為了更令人滿意地回答這個問題,我們修改了Tasklet介面。在 Spring Batch 1.x 中,它相當平淡——不過是一個Callable而已,但在 2.0 中,我們賦予了它更多的靈活性,並將其更多地融入了框架的主流(例如,核心的面向塊的步驟實現現在被實現為一個Tasklet)。這是新的介面


public interface Tasklet {
    ExitStatus execute(StepContribution contribution, 
        AttributeAccessor attributes);
}

其思想是,tasklet 現在可以向其所在的步驟貢獻更多內容,這使其成為實現業務邏輯的更加靈活的平臺。StepContribution在 1.x API 中已經存在,但沒有非常公開地暴露。它的作用是收集對當前StepExecution的更新,而程式設計師無需擔心在另一個執行緒中發生併發修改。這也告訴我們,Tasklet將被重複呼叫(而不是像 1.x 框架中那樣每個步驟只調用一次),因此它可以用於執行更大範圍的業務處理任務。AttributeAccessor是一個塊作用域的鍵值對集合。tasklet 可以使用它來儲存在回滾時會保留的中間結果。

Job 和 Step 屬性的延遲繫結

截至目前(到 M2 版本),我們還未能利用任何新的 Spring 3.0 功能,因為 Spring 3.0 還沒有釋出。但從下一個里程碑(M3)開始,我們將使用新的 Spring EL(表示式語言)功能來實現JobParametersExecutionContext屬性到步驟元件的延遲繫結。這是一個非常需要的功能,我們在 1.x 中有一些特殊情況的臨時解決方案,例如StepExecutionResourceProxy用於將檔名繫結作為作業的輸入引數。Spring Batch 2.0 中提供的一個更通用的解決方案是允許這些步驟屬性繫結到任意元件,透過在適當的 Spring scope 中定義它們,例如

<bean id="step1" parent="simpleStep">
  <property name="itemReader">
    <bean class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
        <property value="#{jobParameters[inputFile]}" />
        ...
    </bean>
  </property>
  ...
</bean>

該 item reader 需要繫結到一個只有在執行時才可用的檔名。為了實現這一點,我們將其宣告為 scope="step" 並使用了 Spring EL 繫結模式#{...}來繫結一個作業引數。同樣的模式也適用於步驟和作業級別的執行上下文屬性。

StepScope在每夜構建快照中可用,但我們仍在使用 Spring 2.5.5,因此 EL 繫結尚未生效。步驟作用域的 bean 也是解決 Spring Batch 舊問題——如何保持步驟執行緒安全——的一個好方法。如果一個步驟依賴於像FlatFileItemReader這樣的有狀態元件,那麼它只需要將該元件定義為 scope="step",框架就會為其建立一個延遲初始化的代理,並且在每次步驟執行時按需建立。當然,為每次作業執行建立一個新的ApplicationContext仍然沒有任何問題,這是 1.x 中保持執行緒不跨作業衝突的最佳實踐。但是現在步驟作用域為您提供了另一個選擇,而且對於大多數 Spring 使用者來說可能更容易理解。

非順序執行

在 1.x 中,作業的模型始終是線性順序的步驟,如果一個步驟失敗,則作業失敗。儘管許多作業仍然符合這種模式,所以它並沒有消失,但在 2.0 中,我們透過引入一些新特性來解除這一限制。這些特性計劃在 M3 版本中實現,因此實現細節可能會改變,但其思想是支援三個特性

  • 條件執行:根據上一個步驟的ExitStatus決定分支到不同的步驟。這包括在 FAILED 狀態時進行分支的能力,這意味著步驟失敗不再對作業是致命的。
  • 暫停執行並等待明確指示繼續。這在例如存在強制手動干預以檢查業務關鍵資料有效性的業務規則的情況下非常有用。
  • 多個步驟的並行執行。如果步驟是獨立的,使用者可以指定哪些分支可以並行執行。
截至撰寫本文時,每夜構建快照包含一個ConditionalJob,支援上述第一個用例。

可伸縮性

Spring Batch 1.x 始終旨在作為單 VM、可能多執行緒的模型,但我們在其中內建了許多支援在多個程序中並行執行的功能。許多專案已成功實現可伸縮的解決方案,這些方案依賴於 Spring Batch 的服務質量特性來確保處理僅按正確順序進行。在 2.0 中,我們計劃更明確地公開這些功能。可伸縮性有兩種方法,我們將支援這兩種方法:遠端分塊(remote chunking)和分割槽(partitioning)。

遠端分塊

遠端分塊是一種在不明確瞭解資料結構的情況下分割步驟工作量的技術。任何輸入源都可以透過在一個程序中讀取(與 1.x 中正常情況一樣)並以塊的形式將項傳送到遠端工作程序來動態分割。遠端程序實現監聽器模式,響應請求、處理資料併發送非同步回覆。請求和回覆的傳輸必須是持久的,具有保證送達和單個消費者,任何 JMS 實現都提供了這些功能。但 Spring Batch 是在 Spring One Americas

配置:註解和 XML 名稱空間

使用註解實現批處理邏輯的想法類似於 Spring @MVC。最終效果是,您無需實現並可能註冊一堆介面(reader、writer、processor、listeners 等),而只需註解一個 POJO 並將其插入到步驟中。有與各種介面相對應的方法級別註解,以及與 job、step 和 chunk 級別屬性相對應的引數級別註解和工廠方法(有點像@ModelParameter@RequestParameter

在 Spring @MVC 中。 Spring Batch 的 XML 名稱空間使得常見事物的配置更加容易。例如,我們上面提到的ConditionalJob具有 XML 配置選項,因此一個簡單的條件執行可能看起來像這樣


<job>
  <step name="gamesLoad" next="playerLoad"/>
  <step name="playerLoad">
    <next on="*" to="summarize"/>
    <next on="FAILED" to="compensate"/>
  </step>
  <step name="compensate"/>
  <step name="summarize"/>
</job>

name= 屬性<stepXML 中的 元素是一個 bean 引用,因此Step的實現在其他地方定義(可能透過註解)。

資料庫 schema 變更

在元資料 schema 中,有一些清理任務和資料模型的擴充套件。我們將為從 1.x 遷移到 2.0 的任何人提供更新指令碼,因此它們不應該引起任何問題,並且肯定會使導航和與元資料互動更容易。對於那些剛接觸 Spring Batch 的人來說,該框架的一些關鍵優勢在於服務質量特性,例如可重啟性和冪等性(僅一次且僅一次處理業務資料)。我們透過在關係資料庫中的共享狀態(在大多數用例中)實現這些特性,並且該資料庫中的資料模型定義在 2.0 中略有改變。

主要變化與ExecutionContext的儲存有關,它以前集中在一個表中,儘管上下文可以與StepExecutionJobExecution相關聯。新模型會更受 DBA 的歡迎,因為它在 DDL 中使關係更加透明。我們還開始將上下文值儲存在 JSON 中,以便人類使用者更容易讀取和跟蹤(單個實體的上下文全部儲存在表的一行中,而不是多行)。

我們還添加了一些關於執行和跳過項的計數和統計資訊,分別統計了每個階段讀取、處理和寫入的總項數。對於不將其執行拆分為讀取、處理、寫入的步驟(或 tasklet),這比需要的更全面,但對於大多數用例,它比僅儲存總項數更合適。

總結

希望本文已經激發了您對 Spring Batch 2.0 的興趣,並且您將有時間下載一個快照或里程碑版本並試用。我們從社群獲得瞭如此多的良好反饋,沒有您的幫助和支援,產品不會像現在這樣好。如果我遺漏了您感興趣的內容,或者提供的細節不夠充分,我深表歉意,但我需要將這篇文章壓縮到合理的部落格篇幅。如果有人感興趣,我可以寫更多內容——請隨時提問。

如果您確實想了解更多資訊,在今年的 Spring One Americas 大會上,您有機會聽取團隊介紹 Spring Batch 2.0 和所有其他 SpringSource 的活動。Lucas Ward 將在一個會議中介紹 Spring Batch 2.0 的特性,我將更詳細地展示其可伸縮性特性。您也可以檢視 論壇 上的討論,或者前往 此處 的主頁。

訂閱 Spring 新聞郵件

透過 Spring 新聞郵件保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速前進。

瞭解更多

獲取支援

Tanzu Spring 透過一個簡單的訂閱提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

近期活動

檢視 Spring 社群的所有近期活動。

檢視全部