Mule的經典實例LoanBroker的學習筆記

最近爲了跟上公司發展,要學一下mule。在瞭解了mule的大概情況之後,便看了看mule的髮型包裏的一個經典實例LoanBroker,整理一下筆記,若有寫得不準確的地方,還望各位大俠不吝賜教。

 

一    一,安裝及部署

             1.     Jdk。最好1.5版本以上吧,我比較超前,用的1.6.安裝完成之後配上環境變量。

             2.     Mule。我下載的是1.4.41.x的差別不是很大,2.x的不太瞭解。然後配上%MULE_HOME%,把%MULE_HOME%\bin加進path變量中。

             3.     MavenMule的部署支持antmaven,不過還是推薦mavenant還是學生時代記憶了。我的maven版本是2.0.7。同樣的配置%MAVEN_HOME%,把%MAVEN_HOME%\bin加入環境變量。

二、       二、 一些說明

  簡單的介紹一下這個應用。



 

 

Component

Description

Loan Broker Service

接受用戶的LoanRequest 請求(它代表一個用戶借款請求),

並且負責聚合返回的LoanQuote表示單個銀行的返回結果)。

Credit Agency Service

檢查用戶的借款的數額是否符合要求

Credit Agency Gateway

連接總線和CreditAaencyService的紐帶

Lender Service

根據用戶的信用和申請借款的數額來選擇哪些銀行接受此次請求。

Lender Gateway

(同上上)

Banking Gateway

loanRequest請求發送到各個指定的銀行。

 

 

這個實例的大概業務流程可以參照mule的官方文檔(http://www.mulesource.org/display/MULEINTRO/LoanBroker+ESB),

三、        三、樣例演示

1.      %MULE_HOME%目錄打開命令行,輸入mvn –Dmaven.test.skip=true,因爲單元測試的代碼可能通不過編譯,所以最好跳過。

2.      編譯成功之後,在%MULE_HOME%\examples\loanbroker目錄下雙擊loanbroker.bat文件。

 

3.     這個LoanBroker提供了多個實現,選擇1,回車;

 

 

 

 

4.     接着mule的服務器就開啓了,如果是第一次啓動mule的話,會有一堆的license要你來確認,直接回車到底。下面這個頁面是關於EJB的配置,直接選1.



 

 

5.     EJB啓動之後,便可以發送借款請求了。在這裏選1。然後輸入我們的借款請求。

 

 

 

 

6.      得到了此次異步調用的結果,如果想看看同步調用有什麼不一樣的話,可以將LoanBrokerApp類中的loanBrokerApp.run(false)改爲true

 

 

 

四、        四、步驟的解析

 

1.       Maven編譯部署後的結構圖如下:



 

 

      其中我們只需要關注esb,而bpmesn我們不去管它。Creditagency是個EJB的工程,可以把它看做一個黑盒,不去管它。重點關注esbcommon兩個工程。

 

2.       Esb工程中有一個很重要的文件——mule的配置文件loan-broker-esb-mule-config.xml。這個配置文件的配置項無非分爲兩個部分。一個是mulemodel的配置,比如,<mule-descriptor/>它代表了一個UMO組件的配置;另一個就是muleTransport的配置,包括trasformerfilerprovider的配置。

當程序啓動以後,由於我們選擇的是1(發送一個標準的借貸請求),所以程序會調用client.dispatch("CustomerRequests", request, null);來發送一個異步請求,其中client是一個MuleClient對象,它可以向MuleServer發送和接受事件對象。request是我們已經封裝好的CustomerQuoteRequest對象,也就是我們的消息對象;"CustomerRequests"是事件目的url,系統會根據這個url將事件發送到vm://customer.requests

 

3.            Mule會把這個事件交給LoanBroker組件來處理,因爲它的inbound-routerendpoint配置爲vm://customer.requests。那麼LoanBroker組件拿到這個事件之後如何來處理這個事件呢?在Mule的官方文檔上有這樣一句話:

 

            When an event is received for your component Mule dynamically chooses the method to invoke based on the payload type of the event.

 

        也就是說mule會根據事件的payload的種類來選擇具體調用的component的方法,在AsynchronousLoanBroker我們找到了這個方法public Object getLoanQuote(CustomerQuoteRequest request) throws LoanBrokerException,而它剛好符合我們的要求。這個方法主要是根據用戶的輸入生成一個LoanBrokerQuoteRequest對象並返回。

 

4.      這個方法調用結束之後事件再如何進行呢?在官方文檔上又有這一句:

 

        The response or outbound message is obtained using the following -

If the method invoked is not void, (Callable.onEvent() returns an Object) the method return value is used. If null is returned no further processing is done for the current request.

If the method is void, the parameters used to invoke the method are used. This assumes that the parameters themselves were altered or there was no change to the event.

 

5.     我們這裏的方法是有返回值的,所以將方法的返回值作爲outbound message。注意此時事件的payload已經爲LoanBrokerQuoteRequest了。

 

6.     注意看LoanBrokeroutbound的類型爲OutboundPassThroughRouter,它不做任何處理將事件傳給endpoint ——CreditAgencyGateway

 

7.     事件會根據配置傳到CreditAgencyGateway這個component裏。這個實現類的實現類爲ReflectionMessageBuilder,文檔上對這個類的解釋爲:

 

         Will try and set the result of an invocation as a bean property on the request message using reflection.

 

         也就是說將在這個component會將方法調用的結果設置爲消息的一個屬性,也就是LoanBrokerQuoteRequest的一個屬性。

 

         這裏的outbound有兩個endpoint,第一個endpoint是發送到一個EJB組件,該組件會根據LoanBrokerQuoteRequest來判斷用戶的信用程度,並將信用信息以xml字符串的形式返回,然後會調用CreditProfileXmlToCreditProfile這一trasformer來將String類型的對象轉換爲CreditProfile這一代表用戶信用度的對象。結果返回後,將第一個返回結果CreditProfile對象設置爲LoanBrokerQuoteRequest的一個屬性,然後再將這個LoanBrokerQuoteRequest發送到第二個endpoint——LenderGateway。注意一下第一個endpoint有一個屬性remoteSync="true”,它表示component將消息同步發送給第一個endpoint,在結果返回前必須等待,否則發往LenderGateway的事件裏LoanBrokerQuoteRequest對象的CreditProfile屬性就還沒有設置了哦!

 

8.     事件這一步就到了LenderGateway這個component了(mule是根據endpoint的配置來判斷事件的流向,這裏只不過名字component的名字和endpoint的名字設置爲一樣的了),這個componentUMOBridgeComponent,它會告訴mule它永遠不會被調用,只是簡單的將inbound-endpoint的輸出作爲outbound-endpoint的輸入,由於它永遠不會被調用,所以性能上會表現比較好。

 

9.       這個componentoutbound的類型爲ChainingRouter,它往往有多個endpoint,會將上一個endpoint的輸出作爲下一個endpoint的輸入。它首先會通過LenderService,根據用戶的信用度和具體的借款額度來選擇可以對用戶提供借貸的銀行列表。根據上面討論的規則,會調用DefaultLender類的setLenderList方法,由於該方法沒有返回值,直接將此LoanBrokerQuoteRequest作爲下一個endpoint的輸入。第二個endpoint BankingGateway將依次調用SetLendersAsRecipients (下一步將詳細表述),ObjectToJMSMessage(將對象轉化爲JMS消息的格式)。

 

10.     BankingGateway這個componentoutbound的類型爲StaticRecipientList,它會根據靜態配置的endpoint來羣發消息,但細細一看配置文件中也沒有相關的配置啊!!其實,在上一步調用SetLendersAsRecipients的如下代碼:

context.getMessage().setProperty(StaticRecipientList.RECIPIENTS_PROPERTY, recipients);其中recipientString類型的銀行列表。

       注意到這個endpoint有個配置<reply-to address="LoanQuotes"/>,它表示每個銀行返回的結果都發送到這個endpoint中。

 

11.  回頭去看LoanBroker這個component有個配置如下:

<response-router timeout="1000000">

    <endpoint address="LoanQuotes"/>

    <router className="org.mule.examples.loanbroker.

routers.BankQuotesResponseAggregator"/>

</response-router>

 

這個response router的作用其實就是將各個銀行返回的結果進行彙總,然後呈現給用戶看。

<!--EndFragment-->

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章