<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 12, comments - 19, trackbacks - 0, articles - 23
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
    異步進(jìn)程通信是面向服務(wù)架構(gòu)(SOA)一個(gè)重要的組成部分,因?yàn)槠髽I(yè)里很多系統(tǒng)通信,特別是與外部組織間的通信,實(shí)質(zhì)上都是異步的。Java消息服務(wù)(JMS)是用于編寫使用異步消息傳遞的JEE應(yīng)用程序的API。傳統(tǒng)的使用JMS API進(jìn)行消息傳遞的實(shí)現(xiàn)包括多個(gè)步驟,例如JNDI查詢隊(duì)列連接工廠和Queue資源,在實(shí)際發(fā)送和接收消息前創(chuàng)建一個(gè)JMS會話。

       Spring框架則簡化了使用JEE組件(包括JMS)的任務(wù)。它提供的模板機(jī)制隱藏了典型的JMS實(shí)現(xiàn)的細(xì)節(jié),這樣開發(fā)人員可以集中精力放在處理消息的實(shí)際工作中,而不用擔(dān)心如何去創(chuàng)建,訪問或清除JMS資源。

       本文將對Spring JMS API作一個(gè)概述,并通過一個(gè)運(yùn)行在JBoss MQ服務(wù)器上的web例程來介紹如何使用Spring JMS API來異步處理(發(fā)送和接收)消息。我將通過傳統(tǒng)JMS實(shí)現(xiàn)和Spring JMS實(shí)現(xiàn)兩者間的比較,來展示使用Spring JMS處理消息是如何的簡單和靈活。

    異步消息傳遞和面向服務(wù)架構(gòu)

      在現(xiàn)實(shí)中,大多數(shù)web請求都是同步處理的。例如,當(dāng)用戶要登入一個(gè)網(wǎng)站,首先輸入用戶名和密碼,然后服務(wù)器驗(yàn)證登錄合法性。如果驗(yàn)證成功,程序?qū)⒃试S該用戶進(jìn)入網(wǎng)站。這里,登錄請求在從客戶端接收以后被即時(shí)處理了。信用卡驗(yàn)證是另一個(gè)同步處理的例子;只有服務(wù)器證實(shí)輸入的信用卡號是有效的,同時(shí)客戶在帳戶上有足夠的存款,客戶才被允許繼續(xù)操作。但是讓我們思考一下在順序處理系統(tǒng)上的支付結(jié)算步驟。一旦系統(tǒng)證實(shí)該用戶信用卡的信息是準(zhǔn)確的,并且在帳戶上有足夠的資金,就不必等到所有的支付細(xì)節(jié)落實(shí)、轉(zhuǎn)賬完成。支付結(jié)算可以異步方式進(jìn)行,這樣客戶可以繼續(xù)進(jìn)行核查操作。

       需要比典型同步請求耗費(fèi)更長時(shí)間的請求,可以使用異步處理。另一個(gè)異步處理的例子是,在本地貸款處理程序中,提交至自動承銷系統(tǒng)(AUS)的信用請求處理過程。當(dāng)借方提交貸款申請后,抵押公司會向AUS發(fā)送請求,以獲取信用歷史記錄。由于這個(gè)請求要求得到全面而又詳細(xì)的信用報(bào)告,包括借方現(xiàn)今和過去的帳戶,最近的付款和其他財(cái)務(wù)資料,服務(wù)器需要耗費(fèi)較長的時(shí)間(幾小時(shí)或著有時(shí)甚至是幾天)來對這些請求作出響應(yīng)。客戶端程序(應(yīng)用)要與服務(wù)器連接并耗費(fèi)如此長的時(shí)間來等待結(jié)果,這是毫無意義的。因此通信應(yīng)該是異步發(fā)生的;也就是,一旦請求被提交,它就被放置在隊(duì)列中,同時(shí)客戶端與服務(wù)器斷開連接。然后AUS服務(wù)從指定的隊(duì)列中選出請求進(jìn)行處理,并將處理得到的消息放置在另一個(gè)消息隊(duì)列里。最后,客戶端程序從這個(gè)隊(duì)列中選出處理結(jié)果,緊接著處理這個(gè)信用歷史數(shù)據(jù)。

    JMS

       如果您使用過JMS代碼,您會發(fā)現(xiàn)它與JDBC或JCA很像。它所包含的樣本代碼創(chuàng)建或JMS資源對象回溯,使得每一次您需要寫一個(gè)新類來發(fā)送和接收消息時(shí),都具有更好的代碼密集性和重復(fù)性。以下序列顯示了傳統(tǒng)JMS實(shí)現(xiàn)所包括的步驟:

    1. 創(chuàng)建JNDI初始上下文(context)。
    2. 從JNDI上下文獲取一個(gè)隊(duì)列連接工廠。
    3. 從隊(duì)列連接工廠中獲取一個(gè)Quene。
    4. 創(chuàng)建一個(gè)Session對象。
    5. 創(chuàng)建一個(gè)發(fā)送者(sender)或接收者(receiver)對象。
    6. 使用步驟5創(chuàng)建的發(fā)送者或接收者對象發(fā)送或接收消息。
    7. 處理完消息后,關(guān)閉所有JMS資源。
    您可以看到,步驟6是處理消息的唯一地方。其他步驟都只是管理與實(shí)際業(yè)務(wù)要求無關(guān)的JMS資源,但是開發(fā)人員必須編寫并維護(hù)這些額外步驟的代碼。

    Spring JMS

       Spring框架提供了一個(gè)模板機(jī)制來隱藏Java APIs的細(xì)節(jié)。JEE開發(fā)人員可以使用JDBCTemplate和JNDITemplate類來分別訪問后臺數(shù)據(jù)庫和JEE資源(數(shù)據(jù)源,連接池)。JMS也不例外。Spring提供JMSTemplate類,因此開發(fā)人員不用為一個(gè)JMS實(shí)現(xiàn)去編寫樣本代碼。接下來是在開發(fā)JMS應(yīng)用程序時(shí)Spring所具有一些的優(yōu)勢。

    1. 提供JMS抽象API,簡化了訪問目標(biāo)(隊(duì)列或主題)和向指定目標(biāo)發(fā)布消息時(shí)JMS的使用。
    2. JEE開發(fā)人員不需要關(guān)心JMS不同版本(例如JMS 1.0.2與JMS 1.1)之間的差異。
    3. 開發(fā)人員不必專門處理JMS異常,因?yàn)镾pring為所有JMS異常提供了一個(gè)未經(jīng)檢查的異常,并在JMS代碼中重新拋出。
    一旦您在JMS應(yīng)用程序中開始使用Spring,您將會欣賞到它在處理異步消息傳遞上的簡便。Spring JMS框架提供多種Java類,可以輕松實(shí)現(xiàn)JMS應(yīng)用。表1列出了這些類的一部分。

       表1. Spring JMS類

    類名功能
    JmsExceptionorg.springframework.jms只要發(fā)生一個(gè)JMS異常,Spring框架就會拋出異常,這個(gè)類是這些所拋出的異常的基(抽象)類。
    JmsTemplate, JmsTemplate102org.springframework.jms.core這些是輔助類,用于簡化JMS的使用,處理JMS資源(如連接工廠,目標(biāo)和發(fā)送者/接收者對象)的創(chuàng)建和釋放。JmsTemplate102是JmsTemplate的子類,使用JMS1.0.2規(guī)范
    MessageCreatororg.springframework.jms.core這是JmsTemplate類使用的回叫接口,它為指定的會話創(chuàng)建JMS消息。
    MessageConverterorg.springframework.jms.support.converter這個(gè)接口充當(dāng)一個(gè)抽象,用來在Java對象與JMS消息之間進(jìn)行轉(zhuǎn)換。
    DestinationResolverorg.springframework.jms.support.destination這是JmsTemplate用來解析目標(biāo)名的接口。該接口的默認(rèn)實(shí)現(xiàn)是DynamicDestinationResolver和JndiDestinationResolve

      在接下來的部分,我將詳細(xì)解釋表1所列的一部分類(例如JmsTemplate,DestinationResolver和MessageConverter)。

    JMSTemplate

      JmsTemplate提供了幾種輔助方法,用來執(zhí)行一些基本操作。要開始使用JmsTemplate前,您需要知道JMS供應(yīng)商支持哪個(gè)JMS規(guī)范,JBoss AS 4.0.2WebLogic 8.1服務(wù)器支持JMS 1.0.2規(guī)范。WebLogic Server 9.0包括了對JMS 1.1規(guī)范的支持。JMS 1.1統(tǒng)一了點(diǎn)對點(diǎn)(PTP)和發(fā)布/訂閱(Pub/Sub)域的編程接口。這種改變的結(jié)果就是,開發(fā)人員可以創(chuàng)建一個(gè)事務(wù)會話,然后在這同一個(gè)JMS會話里,可以從一個(gè)Queue(PTP)中接收消息,同時(shí)發(fā)送另一個(gè)消息到一個(gè)Topic(Pub/Sub)。JMS 1.1向后兼容JMS 1.0,應(yīng)此根據(jù)JMS 1.0編寫的代碼仍可以適用于JMS 1.1。

       JmsTemplate提供多種發(fā)送和接收消息的方法。表2列出了這些方法的一部分。

       表2. JMS template方法

    方法名稱功能
    send發(fā)送消息至默認(rèn)或指定的目標(biāo)。JmsTemplate包含send方法,它通過javax.jms.Destination或JNDI查詢來指定目標(biāo)。
    receive從默認(rèn)或指定的目標(biāo)接收消息,但只會在指定的時(shí)間后傳遞消息。我們可以通過receiveTimeout屬性指定超時(shí)時(shí)間。
    convertAndSend這個(gè)方法委托MessageConverter接口實(shí)例處理轉(zhuǎn)換過程,然后發(fā)送消息至指定的目標(biāo)。
    receiveAndConvert從默認(rèn)或指定的目標(biāo)接收消息。并將消息轉(zhuǎn)換為Java對象。

      目標(biāo)可以通過JNDI上下文保存和獲取。當(dāng)配置Spring程序上下文(application context)時(shí),我們可以用JndiObjectFactoryBean類取得對JMS的引用。DestinationResolver接口是用來把目標(biāo)名稱解析成JMS目標(biāo),當(dāng)應(yīng)用程序存在大量目標(biāo)時(shí),這是非常有用的。DynamicDestinationResolver(DestinationResolver的默認(rèn)實(shí)現(xiàn))是用來解析動態(tài)目標(biāo)的。

       MessageConverter接口定義了將Java對象轉(zhuǎn)換為JMS消息的約定。通過這個(gè)轉(zhuǎn)換器,應(yīng)用程序代碼可以集中于處理事務(wù)對象,而不用為對象如何表示為JMS消息這樣的內(nèi)部細(xì)節(jié)所困饒。SimpleMessageConverter(和SimpleMessageConverter102)是MessageConverter的默認(rèn)實(shí)現(xiàn)。可使用它們分別將String轉(zhuǎn)換為JMS TextMessage,字節(jié)數(shù)組(byte[])轉(zhuǎn)換為JMS BytesMessage,Map轉(zhuǎn)換為JMS MapMessage,和Serializable對象轉(zhuǎn)換為JMS ObjectMessage。您也可以編寫自定義的MessageConverter實(shí)例,通過XML綁定框架(例如JAXBCastorCommons DigesterXMLBeansXStream),來實(shí)現(xiàn)XML文檔到TextMessage對象的轉(zhuǎn)換。

    示例程序

      我將用一個(gè)貸款申請?zhí)幚硐到y(tǒng)(命名為LoanProc)示例來演示如何在JMS應(yīng)用程序中使用Spring。作為貸款申請的一部分,LoanProc通過發(fā)送貸款詳情(貸款I(lǐng)D,借方名字,借方的SSN,貸款期限和貸款數(shù)額),從AUS系統(tǒng)獲得信用歷史詳情。為了簡便起見,我們基于兩個(gè)基本參數(shù)來表示信用歷史詳情:信用分?jǐn)?shù)(又名FICO得分)和貸款數(shù)額。讓我們假設(shè)處理信用檢查請求是按以下業(yè)務(wù)規(guī)則進(jìn)行的:

    1. 如果貸款數(shù)額等于或低于$500,000,借方必須至少有一個(gè)"好"的信用(也就是,借方的FICO得分在680到699之間)。
    2. 如果貸款數(shù)額高于$500,000,借方必須至少有"很好"的信用,意味著借方的信用得分要高于700。

    貸款申請使用案例

      信用請求處理使用案例包括以下幾個(gè)步驟:

    1. 用戶在貸款申請頁面輸入貸款詳情并提交貸款申請。
    2. 發(fā)送請求到一個(gè)名為CreditRequestSendQueue的消息隊(duì)列。然后程序發(fā)送貸款詳情到AUS系統(tǒng),獲取信用歷史詳情。
    3. AUS系統(tǒng)從隊(duì)列中挑出貸款詳情,并使用貸款參數(shù)從它的數(shù)據(jù)庫中獲取信用歷史信息。
    4. 然后AUS將找到的借方的信用歷史信息創(chuàng)建一個(gè)新的消息,發(fā)送到一個(gè)新的名為CreditRequestReceiveQueue的消息隊(duì)列。
    5. 最后,LoanProc從接收隊(duì)列中選出響應(yīng)消息,處理貸款申請來決定是否批準(zhǔn)或否決申請。

      在這個(gè)例程中,兩個(gè)消息隊(duì)列都配置在同一個(gè)JBoss MQ server上。使用案例用圖1的序列圖(SequenceDiagram)表示

    序列圖

    圖1.貸款處理程序的序列圖 (單擊截圖來查看完整視圖)

       下面的表3顯示了在例程中我所使用的不同技術(shù)和開源框架,并按應(yīng)用邏輯層排列。

       表3. 在JMS應(yīng)用程序中使用的框架

    邏輯層技術(shù)/框架
    MVCSpring MVC
    ServiceSpring Framework (version 2.1)
    JMS APISpring JMS
    JMS ProviderJBoss MQ (version 4.0.2)
    JMS ConsoleHermes
    IDEEclipse 3.1

    使用Hermes設(shè)置JMS資源

      為了異步處理消息,首先我們需要消息隊(duì)列發(fā)送和接收消息。我們可以用Jboss里的配置XML文件創(chuàng)建一個(gè)新的消息隊(duì)列,然后使用JMS控制臺瀏覽隊(duì)列的詳細(xì)情況。清單1顯示了配置JMS的XML配置代碼片斷(這個(gè)應(yīng)該加入到j(luò)bossmq-destinations-service.xml文件,位于%JBOSS_HOME%\server\all\deploy-hasingleton\jm文件夾下。)

       清單1.JBoss MQ Server上JMS隊(duì)列的配置

    <!--  Credit Request Send Queue  -->
    <mbean code="org.jboss.mq.server.jmx.Queue"
      name="jboss.mq.destination:service=Queue,name=CreditRequestSendQueue">
      <depends optional-attribute-name="DestinationManager">
     jboss.mq:service=DestinationManager
      </depends>
    </mbean>
    
    <!--  Credit Request Receive Queue  -->
    <mbean code="org.jboss.mq.server.jmx.Queue"
      name="jboss.mq.destination:service=Queue,name=CreditRequestReceiveQueue">
      <depends optional-attribute-name="DestinationManager">
     jboss.mq:service=DestinationManager
      </depends>
    </mbean>
    

      現(xiàn)在,讓我們看看如何使用一個(gè)名為Hermes的JMS工具來瀏覽消息隊(duì)列。Hermes是一個(gè)Java Swing應(yīng)用程序,它可以創(chuàng)建、管理和監(jiān)視JMS提供商(例如JBossMQWebSphereMQActiveMQArjuna服務(wù)器)里的JMS目標(biāo)。從它的網(wǎng)站上下載Hermes,解壓縮.zip文件到本地目錄(例如,c:\dev\tools\hermes)。一旦安裝完成,雙擊文件hermes.bat(位于bin文件夾下)啟動程序。

       要在Hermes里配置JBossMQ服務(wù)器,請參考Hermes網(wǎng)站上的這個(gè)演示。它有著出色的step-by-step可視化指示來配置JBoss MQ。當(dāng)配置一個(gè)新的JNDI初始上下文時(shí),請輸入下面的信息。

    • providerURL = jnp://localhost:1099
    • initialContextFactory = org.jnp.interfaces.NamingContextFactory
    • urlPkgPrefixes = org.jnp.interfaces:org.jboss.naming
    • securityCredentials = admin
    • securityPrincipal = admin

      當(dāng)您創(chuàng)建新的目標(biāo)時(shí),請輸入queue/CreditRequestSendQueue和queue/CreditRequestReceiveQueue。圖2顯示了JMS控制臺的主窗口,其中有為JMS例程創(chuàng)建的新的消息隊(duì)列。

    Hermes中所有目標(biāo)的截圖

    圖 2. Hermes中所有目標(biāo)的截圖.(單擊截圖來查看完整視圖)

       下面的圖3顯示了在從消息發(fā)送者類發(fā)送消息到CreditRequestSendQueue后,Hermes JMS控制臺及消息隊(duì)列的截圖。您可以看見有5個(gè)消息在隊(duì)列中,控制臺顯示了消息詳情,例如消息ID,消息目標(biāo),時(shí)間戳和實(shí)際的消息內(nèi)容。

    Hermes中所有隊(duì)列的截圖

    圖 3. Hermes中所有隊(duì)列的截圖.(單擊截圖來查看完整視圖)

       在例程中使用的隊(duì)列名稱和其他JMS和JNDI參數(shù)見表 4。

       表4. Spring JMS配置參數(shù)

    參數(shù)名稱參數(shù)值
    Initial Context Factoryorg.jnp.interfaces.NamingContextFactory
    Provider URLlocalhost:8080
    Initial Context Factory URL Packagesorg.jnp.interfaces:org.jboss.naming
    Queue Connection FactoryUIL2ConnectionFactory
    Queue Namequeue/CreditRequestSendQueue, queue/CreditRequestReceiveQueue

    Spring配置

      既然我們已經(jīng)有了運(yùn)行例程所需要的JMS目標(biāo),現(xiàn)在該了解用XML Spring配置文件(名為spring-jms.xml)來組配JMS組件的具體細(xì)節(jié)了。這些組件是根據(jù)Inversion of Controller (IOC)設(shè)計(jì)模式里的設(shè)置方式注入原則(setter injection principle),用JMS對象實(shí)例類組配的。讓我們詳細(xì)查看這些組件,并為每一個(gè)JMS組件演示一段XML配置代碼。

       JNDI上下文是取得JMS資源的起始位置,因此首先我們要配置JNDI模板。清單2顯示了名為jndiTemplate的Spring bean,其中列有JNDI初始上下文所必需的常用參數(shù)。

       清單2. JNDI上下文模板

    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <props>
                <prop key="java.naming.factory.initial">
                    org.jnp.interfaces.NamingContextFactory
                </prop>
                <prop key="java.naming.provider.url">
                    localhost
                </prop>
                <prop key="java.naming.factory.url.pkgs">
                    org.jnp.interfaces:org.jboss.naming
                </prop>
            </props>
        </property>
    </bean>
    

      接著,我們配置隊(duì)列連接工廠。清單3顯示了隊(duì)列連接工廠的配置。

       清單3. JMS隊(duì)列連接工廠配置

    <bean id="jmsQueueConnectionFactory"
          class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
            <value>UIL2ConnectionFactory</value>
        </property>
    </bean>
    

      我們定義2個(gè)JMS目標(biāo)來發(fā)送和接收消息。詳情見清單4和5。

       清單4. 發(fā)送隊(duì)列配置

    <bean id="sendDestination"
        class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
            <value>queue/CreditRequestSendQueue</value>
        </property>
    </bean>
    

      清單5. 接收隊(duì)列配置

    <bean id="receiveDestination"
        class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
            <value>queue/CreditReqeustReceiveQueue</value>
        </property>
    </bean>
    

      然后我們再來配置JmsTemplate組件。在例程中我們使用JmsTemplate102。同時(shí)使用defaultDestination屬性來指定JMS目標(biāo)。

       清單6. JMS模板配置

    <bean id="jmsTemplate" 
          class="org.springframework.jms.core.JmsTemplate102">
        <property name="connectionFactory">
            <ref bean="jmsQueueConnectionFactory"/>
        </property>
        <property name="defaultDestination">
            <ref bean="destination"/>
        </property>
        <property name="receiveTimeout">
            <value>30000</value>
        </property>
    </bean>
    

      最后我們配置發(fā)送者和接收者組件。清單7和8分別是Sender 和 Receiver對象的配置。

       清單7. JMS Sender配置

    <bean id="jmsSender" class="springexample.client.JMSSender">
        <property name="jmsTemplate">
            <ref bean="jmsTemplate"/>
        </property>
    </bean>
    

      清單8. JMS Receiver配置

    <bean id="jmsReceiver" class="springexample.client.JMSReceiver">
        <property name="jmsTemplate">
            <ref bean="jmsTemplate"/>
        </property>
    </bean>
    

    測試及監(jiān)視

      我寫了一個(gè)測試類,命名為LoanApplicationControllerTest,用來測試LoanProc程序。我們可以使用這個(gè)類來設(shè)定貸款參數(shù)以及調(diào)用信用請求服務(wù)類。

       讓我們看一下不使用Spring JMS API而使用傳統(tǒng)JMS開發(fā)途徑的消息發(fā)送者實(shí)例。清單9顯示了MessageSenderJMS類里的sendMessage方法,其中包含了使用JMS API處理消息的所有必需步驟。

       清單9. 傳統(tǒng)JMS實(shí)例

    public void sendMessage() {
    
        queueName = "queue/CreditRequestSendQueue";
        System.out.println("Queue name is " + queueName);
    
        /*
         * Create JNDI Initial Context
         */
        try {
            Hashtable env = new Hashtable();
            env.put("java.naming.factory.initial",
                "org.jnp.interfaces.NamingContextFactory");
            env.put("java.naming.provider.url","localhost");
            env.put("java.naming.factory.url.pkgs",
                "org.jnp.interfaces:org.jboss.naming");
    
            jndiContext = new InitialContext(env);
        } catch (NamingException e) {
            System.out.println("Could not create JNDI API " +
                "context: " + e.toString());
        }
    
        /*
         * Get queue connection factory and queue objects from JNDI context.
         */
        try {
            queueConnectionFactory = (QueueConnectionFactory)
            jndiContext.lookup("UIL2ConnectionFactory");
    
            queue = (Queue) jndiContext.lookup(queueName);
        } catch (NamingException e) {
            System.out.println("JNDI API lookup failed: " +
                e.toString());
        }
    
        /*
         * Create connection, session, sender objects.
         * Send the message.
         * Cleanup JMS connection.
         */
        try {
            queueConnection =
                queueConnectionFactory.createQueueConnection();
            queueSession = queueConnection.createQueueSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            queueSender = queueSession.createSender(queue);
            message = queueSession.createTextMessage();
            message.setText("This is a sample JMS message.");
            System.out.println("Sending message: " + message.getText());
            queueSender.send(message);
    
        } catch (JMSException e) {
            System.out.println("Exception occurred: " + e.toString());
        } finally {
            if (queueConnection != null) {
                try {
                    queueConnection.close();
                } catch (JMSException e) {}
            }
        }
    }
    

      現(xiàn)在,我們來看看使用了Spring的消息發(fā)送者實(shí)例。清單10顯示了MessageSenderSpringJMS類中send方法的代碼。

       清單10. 使用Spring API的JMS實(shí)例

    public void send() {
        try {
            ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {
                    "spring-jms.xml"});
    
            System.out.println("Classpath loaded");
    
            JMSSender jmsSender = (JMSSender)appContext.getBean("jmsSender");
    
            jmsSender.sendMesage();
    
            System.out.println("Message sent using Spring JMS.");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    

      如您所見,通過使用配置文件,所有與管理JMS資源有關(guān)的步驟都將交由Spring容器處理。我們只需引用一個(gè)JMSSender對象,然后調(diào)用對象里的sendMessage方法。

    結(jié)束語

      在本文中,我們看到Spring框架是如何使用JMS API簡化異步消息傳遞。Spring去掉了所有使用JMS處理消息所必需的樣本代碼(例如得到一個(gè)隊(duì)列連接工廠,從Java代碼里創(chuàng)建隊(duì)列和會話對象,在運(yùn)行時(shí)使用配置文件對它們進(jìn)行組配)。我們可以動態(tài)的交換JMS資源對象,而不必修改任何Java代碼,這要感謝Inversion of Control (IOC) 原則的力量。

      既然異步消息傳遞是SOA框架的整體構(gòu)成部分,Spring很適合納入到SOA工具集。此外,JMS管理工具(如Hermes)使得創(chuàng)建、管理和監(jiān)督JMS資源變得容易,特別是對于系統(tǒng)管理員來說。

    主站蜘蛛池模板: 国产极品粉嫩泬免费观看 | 亚洲人成免费电影| 亚洲欧洲成人精品香蕉网| 无码的免费不卡毛片视频| 亚洲国产另类久久久精品| 亚洲国产一区国产亚洲 | yellow视频免费在线观看| 全亚洲最新黄色特级网站 | 亚洲色偷偷色噜噜狠狠99| 久久久久国色AV免费看图片| 2020年亚洲天天爽天天噜| 一个人免费观看日本www视频 | 久久国产乱子免费精品| 免费一级毛片女人图片| 亚洲偷自精品三十六区| 午夜爱爱免费视频| 国产精品亚洲色图| MM131亚洲国产美女久久| 久久精品国产免费| 亚洲va精品中文字幕| 你懂的网址免费国产| 国产在线观看免费不卡| 日本一区二区在线免费观看| 亚洲一区无码精品色| 久草免费手机视频| 亚洲AV无码久久久久网站蜜桃 | 国产成人免费高清激情明星| 伊人久久亚洲综合影院首页| 深夜国产福利99亚洲视频| 99久久成人国产精品免费| 亚洲视频在线一区| 免费看无码自慰一区二区| 乱淫片免费影院观看| 亚洲a一级免费视频| 精品国产福利尤物免费| 亚洲欧洲在线观看| 色吊丝永久在线观看最新免费| xxxx日本在线播放免费不卡| 少妇中文字幕乱码亚洲影视| 免费看的一级毛片| 一区二区免费视频|