• <tfoot id="ukgsw"><input id="ukgsw"></input></tfoot>
    
    • 久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
      分享

      Jms基礎知識整理

       nbtymm 2007-03-23

      開始文章之前先澄清幾個概念

      什么是消息

      消息是一個用于在組件和應用程序之間通訊的的方法。消息之間的傳遞是點對點的。任何終端之間都可以相互接受和發(fā)送消息。并且每個終端都必須遵守如下的規(guī)則
       -> 創(chuàng)建消息 -> 發(fā)送消息 -> 接收消息 -> 讀取消息

      為什么要使用消息
      理由很簡單,消息是一個分布式的低耦合通訊方案。A發(fā)送一個消息到一個agent ,B作為接受者去agent上獲取消息。但是A,B不需要同時到agent上去注冊。agent作為一個中轉為A,B提供搞效率的通訊服務。

      開發(fā)者的關注點
      走到這里,我也不想去解釋jms spec上那些抽象且復雜的概念了,說的很白,1年多了我自己也沒弄懂是個什么東西,也沒時間從頭到尾去仔細的看,同時我認為沒必要,我所關注的是如何讓jms跑起來,并且工作正常,所以spec只是個字典,當我需要用的時候才去查。

      開發(fā)者的jms環(huán)境
      遵守簡單明了的原則,所謂jms環(huán)境只是2個對象
      1> ConnectionFactory
      2> Destination

      通常Provider會提供JNDI的對象獲取,具體方法可以去Privider的網站上搜索jndi support

      下面我以jbossMq為介質跑一個簡單的jms,為了保證jms的本質清晰,我沒有使用jbossMq的Api,而是直接調用的jms Api.
      java 代碼
       
      1. package com.javaeye.jms.jboss;  
      2.   
      3. import javax.jms.Connection;  
      4. import javax.jms.ConnectionFactory;  
      5. import javax.jms.Destination;  
      6. import javax.jms.JMSException;  
      7. import javax.jms.MessageConsumer;  
      8. import javax.jms.MessageProducer;  
      9. import javax.jms.Queue;  
      10. import javax.jms.QueueSender;  
      11. import javax.jms.Session;  
      12. import javax.jms.TextMessage;  
      13. import javax.naming.Context;  
      14. import javax.naming.InitialContext;  
      15. import javax.naming.NamingException;  
      16.   
      17. public class JbossNativeJmsImpl {  
      18.      
      19.     /** 
      20.      * @author zuly 
      21.      * 
      22.      * following jms ptp domain, use an simple text message to test 
      23.      * 
      24.      * A jms ptp sender will following the steps below! 
      25.      *     1> get an ConnectionFactory use JNDI Lookup Or Initial it yourself 
      26.      *     2> use this ConnectionFactory to start a jms connection
      27.      *        [spec to jms 1.1 apito get the main idea of it ] 
      28.      *     3> use connection to create a jms session 
      29.      *     4> get a queue destination / messege agent 
      30.      *     5> start the Producer[jms1.1 spec] by a session 
      31.      *     6> get messege Object or initial it yourself by implements the messegeor 
      32.      *        it‘s sub interfaces 
      33.      *     7> call sender or send it selfing 
      34.      *     8> finallized the connection object or it will throw a warning to you! 
      35.      * 
      36.      * @param messege 
      37.      * @throws NamingException 
      38.      * @throws JMSException 
      39.      */  
      40.     public void sendingProcessing(String messege) throws NamingException, JMSException{  
      41.         Context ctx = new InitialContext();  
      42.         ConnectionFactory cf = (ConnectionFactory) ctx.lookup("java:JmsXA");  
      43.         Connection conn = cf.createConnection();  
      44.         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);  
      45.         Destination dest = (Queue) ctx.lookup("queue/A");  
      46.         MessageProducer msgp = session.createProducer(dest);  
      47.         QueueSender sender = (QueueSender) msgp;  
      48.         TextMessage msg = session.createTextMessage();  
      49.         msg.setText(messege);  
      50.         sender.send(msg);  
      51.         conn.close();  
      52.     }  
      53.      
      54.      
      55.      
      56.     /** 
      57.      * @author zuly 
      58.      * 
      59.      * following jms ptp domain, use an simple text message to test 
      60.      * 
      61.      * A jms ptp retriver will following the steps below! 
      62.      *     1> get an ConnectionFactory use JNDI Lookup Or Initial it yourself 
      63.      *     2> use this ConnectionFactory to start a jms connection 
      64.      *        [spec to jms 1.1 api to get the main idea of it ] 
      65.      *     3> use connection to create a jms session 
      66.      *     4> get a queue destination / messege agent 
      67.      *     5> retrive a consumer from session 
      68.      *     6> start the jms connection to retrivte the message 
      69.      *     7> get message from consumer 
      70.      *  
      71.      * @return textMessege 
      72.      * @throws NamingException 
      73.      * @throws JMSException 
      74.      */  
      75.     public String retriveingProcessing() throws NamingException, JMSException{  
      76.         Context ctx = new InitialContext();  
      77.         ConnectionFactory cf = (ConnectionFactory) ctx.lookup("java:JmsXA");  
      78.         Connection conn = cf.createConnection();  
      79.         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);  
      80.         Destination dest = (Queue) ctx.lookup("queue/A");  
      81.         MessageConsumer msgconsumer = session.createConsumer(dest);  
      82.         //MessageListener ml = new JmsListenner();  
      83.         //msgconsumer.setMessageListener(ml);  
      84.         conn.start();  
      85.         TextMessage msg = (TextMessage) msgconsumer.receive();  
      86.         conn.close();  
      87.         System.out.println("messege is" + msg.getText());  
      88.         return msg.getText();  
      89.     }  
      90. }  


      注意retrive函數中comment的掉的兩行,消息Listener的作用是實現異步通訊,但是它有一個約定,必須和發(fā)送者
      保持物理上的分離,針對于jboss而言,就要求這個Listener必須跑在容器外面。這是一個很搞的問題,每天Jms的郵件列表里面都有無數的這樣的問題發(fā)過來。但是回復的人很少。我自己也從來不回復。 其實我也不清楚寫這篇文章到底是出于什么目的,怕只是讓這么一個簡單的問題有一個回答而已。

      把下面這個程序跑起來就可以異步接受消息了。

      java 代碼
       
      1. package com.javaeye.jms.jboss;  
      2.   
      3. import java.util.Properties;  
      4.   
      5. import javax.jms.Connection;  
      6. import javax.jms.ConnectionFactory;  
      7. import javax.jms.Destination;  
      8. import javax.jms.JMSException;  
      9. import javax.jms.MessageConsumer;  
      10. import javax.jms.MessageListener;  
      11. import javax.jms.Session;  
      12. import javax.naming.Context;  
      13. import javax.naming.InitialContext;  
      14. import javax.naming.NamingException;  
      15.   
      16. import com.javaeye.spring.services.jms.mdp.JmsListenner;  
      17.   
      18. public class JbossJmsAsync {  
      19.   
      20.     /** 
      21.      * @param args 
      22.      * @throws NamingException  
      23.      * @throws JMSException  
      24.      */  
      25.     public static void main(String[] args) throws NamingException, JMSException {  
      26.         Properties pops = new Properties();  
      27.         pops.setProperty("jboss.bind.address""0.0.0.0");  
      28.         pops.setProperty("java.naming.factory.initial""org.jnp.interfaces.NamingContextFactory");  
      29.         pops.setProperty("java.naming.factory.url.pkgs""org.jboss.naming:org.jnp.interfaces");  
      30.         pops.setProperty("java.naming.provider.url""localhost");  
      31.         Context ctx = new InitialContext(pops);  
      32.         ConnectionFactory cf = (ConnectionFactory) ctx.lookup("ConnectionFactory");  
      33.         Connection conn = cf.createConnection();  
      34.         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);  
      35.         Destination dest = (Destination) ctx.lookup("queue/A");  
      36.         MessageConsumer msgConsumer = session.createConsumer(dest);  
      37.         MessageListener ml = new JmsListenner();  
      38.         msgConsumer.setMessageListener(ml);   
      39.         conn.start();  
      40.     }  
      41.   
      42. }  


      javaeye的主題好像是spring,為了迎合領導,下面我把這套東西跑在spring里面。同時我發(fā)現spring對jms的包裝真的簡單,而且還提供了一個模版,雖然這個模版的接口是在是很羅唆。

      ps:今天是第1次用spring在reference里找了半天找不到方法注入的辦法,于是google了一個注入辦法,不合理的地方請大家指出。首先我通過方法來注入ConnectionFactory和Destination這兩個對象來支撐jms環(huán)境

      java 代碼
       
      1. package com.javaeye.spring.services.jms.mdp;  
      2.   
      3. import java.util.Properties;  
      4.   
      5. import javax.jms.ConnectionFactory;  
      6. import javax.jms.Destination;  
      7. import javax.jms.Queue;  
      8. import javax.naming.Context;  
      9. import javax.naming.InitialContext;  
      10. import javax.naming.NamingException;  
      11.   
      12. public class UserJmsTransactionUtil {  
      13.   
      14.     private String connectionFactoryJndiLookUp;  
      15.      
      16.     private String destinationJndiLookUp;  
      17.      
      18.     private String localConnectionFactoryJndiLookUp;  
      19.      
      20.     private String containerType;  
      21.      
      22.      
      23.     public String getConnectionFactoryJndiLookUp() {  
      24.         return connectionFactoryJndiLookUp;  
      25.     }  
      26.   
      27.   
      28.   
      29.     public void setConnectionFactoryJndiLookUp(String connectionFactoryJndiLookUp) {  
      30.         this.connectionFactoryJndiLookUp = connectionFactoryJndiLookUp;  
      31.     }  
      32.   
      33.   
      34.   
      35.     public String getDestinationJndiLookUp() {  
      36.         return destinationJndiLookUp;  
      37.     }  
      38.   
      39.   
      40.   
      41.     public void setDestinationJndiLookUp(String destinationJndiLookUp) {  
      42.         this.destinationJndiLookUp = destinationJndiLookUp;  
      43.     }  
      44.   
      45.   
      46.   
      47.     public ConnectionFactory getConnectionFactory() throws NamingException{  
      48.         Context ctx = new InitialContext();  
      49.         ConnectionFactory cf = (ConnectionFactory) ctx.lookup(connectionFactoryJndiLookUp);  
      50.         return cf;  
      51.     }  
      52.      
      53.      
      54.     public Destination getJmsDestination() throws NamingException{  
      55.         Context ctx = new InitialContext();  
      56.         Destination dest = (Queue) ctx.lookup(destinationJndiLookUp);  
      57.         return dest;  
      58.     }  
      59.      
      60.      
      61.     public ConnectionFactory getQueueConnectionFactory() throws NamingException{  
      62.         Properties pops = new Properties();  
      63.         pops.setProperty("jboss.bind.address""0.0.0.0");  
      64.         pops.setProperty("java.naming.factory.initial""org.jnp.interfaces.NamingContextFactory");  
      65.         pops.setProperty("java.naming.factory.url.pkgs""org.jboss.naming:org.jnp.interfaces");  
      66.         pops.setProperty("java.naming.provider.url""localhost");  
      67.         Context ctx = new InitialContext(pops);  
      68.         ConnectionFactory cf = (ConnectionFactory) ctx.lookup(localConnectionFactoryJndiLookUp);  
      69.         return cf;  
      70.     }  
      71.      
      72.      
      73.     public Destination getLocalJmsDestination() throws NamingException{  
      74.         Properties pops = new Properties();  
      75.         pops.setProperty("jboss.bind.address""0.0.0.0");  
      76.         pops.setProperty("java.naming.factory.initial""org.jnp.interfaces.NamingContextFactory");  
      77.         pops.setProperty("java.naming.factory.url.pkgs""org.jboss.naming:org.jnp.interfaces");  
      78.         pops.setProperty("java.naming.provider.url""localhost");  
      79.         Context ctx = new InitialContext(pops);  
      80.         Destination dest = (Destination) ctx.lookup(destinationJndiLookUp);  
      81.         return dest;  
      82.     }  
      83.   
      84.   
      85.   
      86.     public String getLocalConnectionFactoryJndiLookUp() {  
      87.         return localConnectionFactoryJndiLookUp;  
      88.     }  
      89.   
      90.   
      91.   
      92.     public void setLocalConnectionFactoryJndiLookUp(  
      93.             String localConnectionFactoryJndiLookUp) {  
      94.         this.localConnectionFactoryJndiLookUp = localConnectionFactoryJndiLookUp;  
      95.     }     
      96. }

      發(fā)送端的配置如下

      xml 代碼
       
      1. <beans>  
      2.     <bean id="userJmsUtil" class="com.javaeye.spring.services.jms.mdp.UserJmsTransactionUtil">  
      3.         <property name="connectionFactoryJndiLookUp" value="java:JmsXA"><!--</span-->property>  
      4.         <property name="destinationJndiLookUp" value="queue/A"><!--</span-->property>  
      5.         <property name="localConnectionFactoryJndiLookUp" value="ConnectionFactory"><!--</span-->property>  
      6.     <!--</span-->bean>  
      7.   
      8.     <bean id="connectionFactory" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">  
      9.         <property name="targetObject" ref="userJmsUtil"><!--</span-->property>  
      10.         <property name="targetMethod" value="getConnectionFactory"><!--</span-->property>  
      11.     <!--</span-->bean>  
      12.       
      13.     <bean id="queue" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">  
      14.         <property name="targetObject" ref="userJmsUtil"><!--</span-->property>  
      15.         <property name="targetMethod" value="getJmsDestination"><!--</span-->property>  
      16.     <!--</span-->bean>  
      17.           
      18.     <bean id="jmsQueue" class="org.springframework.jms.core.JmsTemplate">  
      19.         <property name="connectionFactory" ref="connectionFactory"><!--</span-->property>  
      20.         <property name="defaultDestination" ref="queue"><!--</span-->property>  
      21.         <property name="messageConverter">  
      22.             <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"><!--</span-->bean>  
      23.         <!--</span-->property>  
      24.     <!--</span-->bean>  
      25. <!--</span-->beans>  

      ps:javaeye的模版工具bug還真多,不管了.

      如果使用Listenner的化,一樣需要遵守發(fā)送者和接收者物理隔離的原則,我的做法是把發(fā)送者配到一個xml中,在把接受者配到另外一個xml中去,發(fā)送的配置綁定到容器里,接收者的跑在本地.否則spring初始化是過不去的.

      下面這個程序是發(fā)送消息的程序.使用了spring的模版,發(fā)條消息比new個對象還簡單.同時spring還提供了適配器的接口,一樣通過聲明式的配置,這樣可以在同一個接口里發(fā)送各種類型的消息了.同時支持事務,我還不知道這個有什么用呵呵,第1次使用嘛!但是就使用上來說,spring是最簡單的.2者都只需要注入一個對象而已.

      java 代碼
       
      1. @Test public void send(){  
      2.     ApplicationContext ac = new FileSystemXmlApplicationContext("jms.xml");  
      3.     BeanFactory bf = ac;  
      4.     JmsTemplate jt = (JmsTemplate) bf.getBean("jmsQueue");  
      5.     jt.convertAndSend("2132134");  
      6. }  


      接收端的配置如下
      xml 代碼
       
      1. xml version="1.0" encoding="UTF-8"?>  
      2. >  
      3. <beans>  
      4.   
      5.     <bean id="listenner" class="com.javaeye.spring.services.jms.mdp.JmsListenner"><!--</span-->bean>  
      6.       
      7.     <bean id="userJmsUtil" class="com.javaeye.spring.services.jms.mdp.UserJmsTransactionUtil">  
      8.         <property name="connectionFactoryJndiLookUp" value="java:JmsXA"><!--</span-->property>  
      9.         <property name="destinationJndiLookUp" value="queue/A"><!--</span-->property>  
      10.         <property name="localConnectionFactoryJndiLookUp" value="ConnectionFactory"><!--</span-->property>  
      11.     <!--</span-->bean>  
      12.   
      13.     <bean id="localConnectionFactory" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">  
      14.         <property name="targetObject" ref="userJmsUtil"><!--</span-->property>  
      15.         <property name="targetMethod" value="getQueueConnectionFactory"><!--</span-->property>  
      16.     <!--</span-->bean>  
      17.       
      18.     <bean id="localDestination" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">  
      19.         <property name="targetObject" ref="userJmsUtil"><!--</span-->property>  
      20.         <property name="targetMethod" value="getLocalJmsDestination"><!--</span-->property>  
      21.     <!--</span-->bean>  
      22.       
      23.     <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
      24.         <property name="concurrentConsumers" value="5"><!--</span-->property>  
      25.         <property name="connectionFactory" ref="localConnectionFactory"><!--</span-->property>  
      26.         <property name="destination" ref="localDestination"><!--</span-->property>  
      27.         <property name="messageListener" ref="listenner"><!--</span-->property>  
      28.     <!--</span-->bean>  
      29. <!--</span-->beans>  


      接收端由于需要從jbossmq里取ConnectionFactory和Destination,所以,我調用的是userJmsUtil的localLookup.這個函數的作用等同于發(fā)送者的那個函數,只不過前者是容器外獲取,而后者是容器內的而已.

      java 代碼
       
      1. package com.javaeye.spring.services.jms.mdp;  
      2.   
      3. import javax.jms.JMSException;  
      4. import javax.jms.Message;  
      5. import javax.jms.MessageListener;  
      6. import javax.jms.TextMessage;  
      7.   
      8. public class JmsListenner implements MessageListener {  
      9.   
      10.     public void onMessage(Message message) {  
      11.         try {  
      12.             TextMessage msg = (TextMessage) message;  
      13.             System.out.println(msg.getText());  
      14.         } catch (JMSException e) { e.printStackTrace(); }  
      15.     }  
      16.   


      spring對jms的整合里提到了一個jms provider ActiveMQ,要用一個開源框架要做的第一件事就是先跑一個demo起來,同樣,我們要做的事還是獲取ConnectionFactory和Destination對象,還好,ActiveMQ的JNDI實現比jbossMQ還要簡單,直接通過一個本地的Context就可以查到了,具體的可以參照ActiveMQ官方的支持文檔.

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多

        主站蜘蛛池模板: 亚洲香蕉网久久综合影视| 国产成人亚洲综合图区| 亚洲欧洲精品日韩av| 又大又爽又硬的曰皮视频| 天干天干天啪啪夜爽爽AV| 日韩有码精品中文字幕| 精品国产美女福到在线不卡| 亚洲中文久久久精品无码| 国产免费高清69式视频在线观看| 无码AV动漫精品一区二区免费| 国产精品二区中文字幕| 国产精品色内内在线播放| 国产福利社区一区二区| 国产成人综合欧美精品久久 | 久久久久高潮综合影院| 天堂中文8资源在线8| 呦交小U女精品视频| 国内精品久久久久影院网站| 国产边打电话边被躁视频| 亚洲av永久无码精品水牛影视 | 国产人妻久久精品一区| 免费无码一区无码东京热| 精品一区二区三区自拍图片区| 久久精品第九区免费观看| 亚洲爆乳精品无码AAA片| 四虎国产精品免费久久久| 影音先锋啪啪av资源网站| 日日噜噜夜夜狠狠视频| 亚洲国产精品久久久天堂麻豆宅男| A级毛片100部免费看| 怡红院一区二区三区在线| 波多野结衣在线精品视频| 不卡AV中文字幕手机看| 久久精品国产99国产精品严洲 | 国产精品区一区第一页| 久久99国产精品久久99小说| 亚洲AVAV天堂AV在线网阿V| 少妇愉情理伦片丰满丰满午夜 | 天干天干天啪啪夜爽爽色| 国产午夜精品福利视频| 国产精品毛片无码|