領先一步
VMware 提供培訓和認證,助力您的職業發展。
瞭解更多我們很高興宣佈 '貸款經紀人' 參考實現的第一個部分。'貸款經紀人' 概念已成為展示 企業整合模式 (EIP)(由 Gregor Hohpe 和 Bobby Woolf 撰寫)事實上的參考領域,而本次貸款經紀人參考實現的部分展示瞭如何使用 Spring Integration (SI) 框架實現和應用企業整合模式。
EIP 架構的核心是非常簡單但強大的 管道和過濾器 以及 訊息 概念。端點(過濾器)透過通道(管道)相互連線。生產端點將訊息傳送到通道,訊息由消費端點檢索。此架構旨在定義描述端點之間資訊如何交換的各種機制,而無需瞭解這些端點是什麼或它們正在交換什麼資訊,從而提供了一種非常鬆散耦合和靈活的協作模型,同時也將整合關注點與業務關注點解耦。EIP 透過進一步定義以下內容擴充套件了此架構:
Spring Integration (SI) 訊息框架旨在提供一個構建在企業整合模式之上的基於 POJO 的程式設計模型。
提交貸款報價請求 - 訊息閘道器
訊息閘道器模式提供了一種訪問訊息系統的簡單機制,包括我們的貸款經紀人。在 SI 中,您將閘道器定義為一個普通的 Java 介面 (POJO),無需提供實現,透過 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>
這將建立一個名為 'preScreening' 的 bean,作為一個 SI 鏈 端點,它也定義了 輸入/輸出-通道 來接收和傳送訊息。上面的 鏈 由 3 個 header-enricher 處理器組成。第一個將透過使用 SpEL 來訪問 訊息歷史 並根據呼叫的閘道器方法確定此頭的值來設定 RESPONSE_TYPE 頭。
此示例說明了如何使用 SpEL 在確定頭值時執行簡單的評估,但我們不提倡使用 SpEL 執行復雜的業務邏輯接下來,我們有一個對映到一個處理過程的 header-enricher,該過程負責從信用局(當前是模擬 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,該元素提供了一個預設的 aggregator 和 correlation 策略。預設的關聯策略基於 $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 屬性。事實上,我們沒有明確定義任何一個 channel。與其他的訊息系統類似,SI 會根據需要自動建立 input 和預設的 reply 通道,這為您提供了另一種進一步簡化 Spring Application Context 配置的方式。
在下一期中,我們將透過用這些介面卡替換我們的模擬服務來演示 Spring Integration 中可用的各種遠端介面卡和技術,並將引入與“貸款經紀人”用例相關的非同步整合風格。
資源:
'Loan Broker' 參考實現隨 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) 為此部落格提供的幫助!