領先一步
VMware 提供培訓和認證,以加速您的進度。
了解更多我們很高興宣布推出「貸款經紀人」參考實作的第一部分。「貸款經紀人」概念已成為展示 企業整合模式 (EIP) 的事實參考領域 - 作者為 Gregor Hohpe 和 Bobby Woolf,而此貸款經紀人 RI 的第一部分示範了如何使用 Spring Integration (SI) 框架實現和應用企業整合模式。
EIP 架構的核心是非常簡單但功能強大的概念:管道與篩選器 和 訊息。端點(篩選器)透過通道(管道)相互連接。生產端點將訊息傳送到通道,而訊息由消費端點檢索。 此架構旨在定義各種機制,描述端點之間如何交換資訊的方式,而無需了解這些端點是什麼或它們正在交換什麼資訊,從而提供非常鬆散耦合且靈活的協作模型,同時也將整合考量與業務考量分離。EIP 透過進一步定義來擴展此架構
Spring Integration (SI) 訊息傳遞框架旨在提供基於 POJO 的程式設計模型,該模型建立在企業整合模式之上。
提交貸款報價請求 - 訊息閘道
訊息閘道模式提供了一種簡單的機制來存取訊息傳遞系統,包括我們的貸款經紀人。在 SI 中,您將閘道定義為 Plain Old Java Interface(無需提供實作),透過 XML <gateway> 元素或透過註解進行配置,並像任何其他 Spring bean 一樣使用它。SI 將透過產生訊息(有效負載映射到方法的輸入參數)並將其發送到指定的通道,來處理委派和將方法調用映射到訊息傳遞基礎設施。
LoanBrokerGateway.java 是代表消費者使用的訊息閘道的介面
閘道 XML 配置
<int:gateway id="loanBrokerGateway"
default-request-channel="loanBrokerPreProcessingChannel"
service-interface="org.springframework.integration.loanbroker.LoanBrokerGateway"/>
在上述配置中,每當在 'loanBrokerGateway' bean 上調用任何方法時,都會建構一個訊息並將其發送到 'loanBrokerPreProcessingChannel'。
我們對訊息閘道的定義 (LoanBrokerGateway.java) 為消費者提供了兩種與貸款經紀人互動的方式。消費者可以透過調用 getLoanQuote(loanRequest) 方法請求單一(最佳)報價,或透過調用 getAllLoanQuotes(loanRequest) 方法請求所有報價。這表示我們的貸款經紀人必須知道貸款請求的類型。我們也知道有一些預先篩選步驟,例如取得和評估消費者的信用評分,因為某些頂級銀行通常只接受信用評分符合最低要求的消費者的報價請求。
基本上,整個過程類似於看醫生,在看到真正的醫生之前,您會先見到護士,護士會測量您的體溫、血壓等,並記錄醫生需要的「元資訊」列表。在 EIP 中,訊息是一個簡單的結構,由訊息有效負載和訊息標頭組成。訊息標頭是儲存與訊息相關的元資訊的絕佳機制。那麼,我們如何使用額外資訊豐富我們的訊息呢?EIP 定義了 內容豐富器 模式,該模式描述了如何使用額外資訊擴充訊息。Spring Integration 提供了 <header-enricher> 元素,讓您可以快速豐富傳輸中的訊息。但是,由於我們的貸款經紀人必須在發送報價之前執行多項任務,因此如果還有一種機制可以從一組獨立的任務中組合流程,那就太好了。
組合訊息處理器模式描述了圍繞建立端點的規則,這些端點保持對訊息流的控制,訊息流由多個訊息處理器組成。在我們的案例中,預先篩選流程包含 3 個步驟:a) 確定貸款請求的類型; b) 取得消費者的信用記錄和評分; c) 確定(基於某些標準)通道列表(每個通道對應一家銀行)。
Spring Integration 允許您透過 <chain> 元素組合複雜的處理器
<int:chain id="preScreening" input-channel="loanBrokerPreProcessingChannel" output-channel="banksDistributionChannel">
<int:header-enricher>
<int:header name="RESPONSE_TYPE"
expression="headers.history.iterator().next().attributes['method'].equals('getLoanQuote') ? 'BEST' : 'ALL'" />
</int:header-enricher>
<int:header-enricher>
<int:header name="CREDIT_SCORE" ref="creditBureau" method="getCreditScore"/>
</int:header-enricher>
<int:header-enricher>
<int:header name="BANKS" ref="bankSelector" method="selectBankChannels"/>
</int:header-enricher>
</int:chain>
這將建立一個 bean 'preScreening' 作為 SI 鏈端點,它也定義了一個 輸入/輸出-通道 來接收和發送訊息。上面的鏈由 3 個 header-enricher 處理器組成。第一個將透過利用 SpEL 同時存取 訊息歷史記錄 並根據調用的閘道方法確定此標頭的值來設定 RESPONSE_TYPE 標頭。
此範例說明了如何在確定標頭值時使用 SpEL 執行簡單的評估,但我們不提倡使用 SpEL 執行複雜的業務邏輯接下來,我們有一個 header-enricher,它映射到一個負責從徵信局取得信用評分的流程(目前為 Stub CreditBureauStub)並設定 CREDIT_SCORE 標頭。最後一個 header-enricher 使用 BankChannelSelector(請參閱 bankSelector 配置)。BankChannelSelector.selectBankChannels(..) 方法的實作將訊息作為輸入,並傳回一個 Set<String> 值,其中包含通道的名稱,這些通道將設定為 BANKS 標頭。這完成了我們的預先篩選流程,我們的貸款經紀人現在準備好透過 banksDistributionChannel 向每家選定的銀行發送貸款請求。
BANKS 標頭定義了動態產生和篩選的通道列表,每個通道都充當代表銀行的接收者。我們需要一個端點,允許我們將相同的訊息發送到所有接收者。
將貸款報價請求分發到選定的銀行 - 收件者列表
下面的 XML 配置顯示了如何配置此路由器
<int:router id="bankRecipientListRouter" input-channel="banksDistributionChannel"
expression="headers['BANKS']"
apply-sequence="true"/>
您可以清楚地看到我們如何透過透過通道(管道)連接各種端點(篩選器)來組裝貸款經紀人,同時傳遞訊息。您也可以看到我們正在透過基於 POJO 的程式設計技術來完成它,幾乎沒有使用 Spring Integration API(只有 BankChannelSelector.java)。SI 負責將我們的 POJO 與訊息傳遞基礎設施介接。貸款經紀人需要做的最後一件事是接收來自銀行的貸款報價,按消費者聚合它們(我們不想向另一個消費者顯示來自一個消費者的報價),根據消費者的選擇標準(單一最佳報價或所有報價)組裝回覆,然後回覆消費者。
聚合貸款報價回覆 - 聚合器
聚合器模式描述了一個端點,該端點將相關的訊息分組為單個訊息。可以提供標準和規則來確定聚合和關聯策略。SI 提供了聚合器模式的幾種實作以及基於方便命名空間的配置。
我們的貸款經紀人透過 <aggregator> 元素定義了一個 'loanQuoteAggregator' bean,它提供了預設的聚合器和關聯策略。預設關聯策略根據 $corelationId 標頭關聯訊息(請參閱 關聯識別碼 模式)。有趣的是,我們從未提供此標頭的值。 它是由收件者列表路由器在稍早自動設定的,當時它為每家銀行產生了一個單獨的訊息。
訊息關聯後,它們會發佈到實際的聚合器實作。雖然 SI 提供了預設聚合器,但其策略(從所有訊息收集有效負載列表並使用此列表作為有效負載建構新訊息)不符合我們的要求。原因是我們的消費者可能需要單一最佳報價或所有報價。為了傳達消費者的請求,我們在流程的早期設定了 RESPONSE_TYPE 標頭。現在我們必須評估此標頭並傳回所有報價(預設聚合策略會起作用)或最佳報價(預設聚合策略將不起作用,因為我們必須確定哪個貸款報價是最佳的)。
<int:aggregator id="loanQuoteAggregator" input-channel="quotesAggregationChannel" method="aggregateQuotes">
<bean class="org.springframework.integration.loanbroker.LoanQuoteAggregator"/>
</int:aggregator>
顯然,選擇最佳報價可能基於複雜的標準,並且會影響聚合器的複雜性,但目前我們使其變得簡單。如果消費者想要最佳報價,我們將選擇利率最低的報價。為了實現這一點,LoanQuoteAggregator.java 將對所有報價進行排序並傳回第一個。 LoanQuote.java 實作了 Comparable,它根據 rate 屬性比較報價。
建立回覆訊息後,它會被發送到啟動流程的訊息閘道的 default-reply-channel(因此是消費者)。我們的消費者收到了貸款報價!
需要注意的一個重要事項是,我們沒有在 <gateway> 元素上定義 default-reply-channel 屬性。事實上,我們沒有明確定義單個通道。與其他訊息傳遞系統類似,SI 將根據需要自動建立輸入和預設回覆通道,為您提供另一種進一步簡化 Spring 應用程式內容配置的方法。
在下一部分中,我們將透過使用這些轉接器替換我們的 Stub 服務來示範 Spring Integration 中可用的各種遠端轉接器和技術,並將介紹與「貸款經紀人」使用案例相關的非同步整合樣式。
資源:
「貸款經紀人」參考實作隨 Spring Integration 2.0.M3 的發布而提供(請參閱「下載」部分)。它作為獨立的 Eclipse/Maven 專案分發。您也可以從我們的 Subversion 儲存庫中將其檢出為專案。
$> svn co https://src.springframework.org/svn/spring-integration/trunk/spring-integration-samples/loan-broker/ loan-broker $> cd loan-broker $> mvn install
相關連結:Spring Integration Spring Integration in Action 企業整合模式 Spring Integration 入門指南 (Joshua Long) 敏捷 SOA - 第 1、2 和 3 部分 (Tom McCuch)
感謝 Gary Russel (Spring Source,SI 提交者) 和 Dave Turanski (Spring Source) 協助撰寫此部落格!