现在的位置: 首页 > 综合 > 正文

JMS学习笔记

2014年01月27日 ⁄ 综合 ⁄ 共 8092字 ⁄ 字号 评论关闭

 

一、概述

·JMS是用于面向消息的中间件相互通信的应用程序接口(API)

·既支持点对点(P2P)的域,也支持发布/订阅(Publish/Subscibe)类型的域

·提供两大功能:消息生产和消息消费

·JMS提供的消息服务包括两种机制:

1、P2P 单个消费者消费掉(Queue队列)

Client1发送消息给消息服务中的一个队列,而Client2则从这个队列中取出消息

2、发布/订阅 为持久地订阅者则会保存到MQ并处于监听状态(Topic主题)

类似于广播,Client1向服务器中的一个消息主题发送消息,对于这个消息主题感兴趣的客户端可以预约这个消息主题,当主题存在数据时,所以预约过这个主题的客户端都会接收到。

·Sun两个JMS的版本:1.02版本 QueueConnectionFactory  TopicConnectionFactory

1.1版本,统一成为ConnectionFactory

二、概念

·Destination 目的地 用来表示这些管理对象的抽象目的地资源

·Session 会话 一个会话对象是一个单线程的上下文对象,用于产生消息和消费消息,是JVM向外提供的资源,也是一个JMS对象,它既是产生消息生产者和消费者的工厂,也是创建主题消息对象和点对点消息对象的工厂

TopicPublisher publisher = session.createPublisher(topic);

        TopicSubscriber subscriber = session.createSubscriber(topic);

        QueueSender sender = session.createSender(queue);

        QueueReceiver receiver = session.createReceiver(queue);

TextMessage msg = publisher.session.CreateTextMessage();

        TextMessage msg = sender.session.CreateTextMessage();

·Connection 一个连接对象是由客户端激活的客户端与服务提供者之间的连接

·Message消息 服务提供者与客户端之间传递信息所使用的信息单元,{消息头、消息属性、消息体组成}

·MessageProducer 消息生产者  消息产生由JMS客户端完成,服务提供者只负责管理这些消息,通过Publish(Message msg)和send(Message msg)完成

·MessageConsumer 消息消费者   接收来自某个队列的消息  通过 Message receiver()来接收

三、JMS使用步骤(9个步骤)

由JNDI发现ConnectionFactory,然后创建一个连接实例(Connection),由Connection创建一个Session,然后由Session创建消息生产者(Producer),也可以创建消息消费者(Consumer),无论生产者还是消费者都需要访问JMS的目标对象(Destination)。当然在使用消费方式时,可以建立消息的监听者(Listener),当产生一个消息时,监听者会得到通知。

步骤1:创建JNDI上下文,并找到创建JMS的工厂类

Hashtable env = new Hashtable(); 

env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory"); 

env.put(Context.PROVIDER_URL,"ldap://192.168.100.56:1039/"); 

Context iniCtx = new InitialContext(env);

TopicConnectionFactory tcf = (TopicConnectionFactory)iniCtx.lookup("ConnectionFactory");

步骤2:查找JMS的目标对象

Topic topic = (Topic)iniCtx.lookup("topic/testTopic");

步骤3:创建JMS

TopicConnection conn = tcf.createTopicConnection();//只要在这里加入user,pwd参数,该消息为持久性消息

步骤4:创建会话

TopicSession session = conn.createTopicSession(false,Session.Auto_ACKNOWLEDGE);

步骤5:创建消息的生产者和消费者

TopicPublisher publisher = session.createPublisher(topic);

TopicSubscriber subscriber = session.createSubscriber(topic);

步骤6:注册消息监听者

TextListener listener = new TextListener();

Subscriber.setMessageListener(listener);

步骤7:开始JMS的连接

Conn.start();

步骤8:发送和接收消息

Publisher.publish(Message message);

Message message = subscriber.receive();

步骤9:停止和关闭JMS连接

Conn.stop();

Session.close();

Conn.close();

 

-----------------------spring 封装JMS----------------------------

Spring 中对JMS进行了封装,另使用编写变得更简单.对于1.1的JMS其有JmsTemplate,而对于1.02其有JmsTemplate102

而Spring中的JMS对于Queue和Topic方式并不关心,都整合到一起用了!!

这里的JMSTemp需要指定 connectionFactory(org.springframework.jndi.JndiObjectFactoryBean)和 defaultDestination(org.springframework.jndi.JndiObjectFactoryBean)    注意 1.02中必须要设置pubsubDomain属性,是否以主题形式发送   

   JMS发送方法

       jmsTemplate.send(new MessageCreator() {

             public Message createMessage(Session session) throws JMSException {

                  //利用Session创建消息并返回该消息实例就行了

             }

    }

    

   JMS接收方法

      Message Msg = jmsTemplate.receive();

 

 

========================jms实例=========================

Spring JMS

        Spring框架提供了一个模板机制来隐藏Java APIs的细节。开发人员可以使用JDBCTemplate和JNDITemplate类来分别访问后台数据库和JEE资源(数据源,连接池)。JMS也不例外,Spring提供JMSTemplate类,因此开发人员不用为一个JMS实现去编写样本代码。接下来是在开发JMS应用程序时Spring所具有一些的优势。

 

提供JMS抽象API,简化了访问目标(队列或主题)和向指定目标发布消息时JMS的使用。

开发人员不需要关心JMS不同版本(例如JMS 1.0.2与JMS 1.1)之间的差异。

开发人员不必专门处理JMS异常,因为Spring为所有JMS异常提供了一个未经检查的异常,并在JMS代码中重新抛出。

实战:下面是我在学习过程中的一个入门实例

1.  在web.xml文件中配置一个spring用的上下文:

 

 

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/jmsconfig.xml</param-value>

</context-param>

<!-- 配置Spring容器 -->

<listener>

    <listener-class>

           org.springframework.web.context.ContextLoaderListener

       </listener-class>

</listener>

2.  创建jmsconfig.xml用来装配jms,内容如下:

 

 

<?xml version="1.0" encoding="UTF-8"?>  

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

    "http://www.springframework.org/dtd/spring-beans.dtd">  

 

<beans>

    <bean id="jmsConnectionFactory"

        class="org.springframework.jndi.JndiObjectFactoryBean">

        <property name="jndiName">

            <value>UIL2ConnectionFactory</value>

        </property>

    </bean>

   

    <bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">

        <property name="jndiName">

            <value>topic/scJms</value>

        </property>

    </bean>

   

    <!--  Spring JmsTemplate config -->

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">

        <property name="connectionFactory">

            <bean

                class="org.springframework.jms.connection.SingleConnectionFactory">

                <property name="targetConnectionFactory"

                    ref="jmsConnectionFactory"/>

            </bean>

        </property>

    </bean>

   

    <!-- POJO which send Message uses  Spring JmsTemplate --> <!--配置消息发送者-->

    <bean id="messageProducer" class="co.transport.jms.MessageProducer">

        <property name="template" ref="jmsTemplate"/>

        <property name="destination" ref="destination"/>

    </bean>

   

    <!--  Message Driven POJO (MDP) -->

    <bean id="messageListener" class="co.transport.jms.MessageConsumer"/>

   

    <!--  listener container,MDP无需实现接口 -->

    <bean id="listenerContainer"

        class="org.springframework.jms.listener.DefaultMessageListenerContainer">

        <property name="connectionFactory" ref="jmsConnectionFactory"/>

        <property name="destination" ref="destination"/>

        <property name="messageListener" ref="messageListener"/>

    </bean>

</beans>

 

其中:

      1)   jmsConnecmactory用的是Jboss自带的一个ConnectionFactory,可以在Jboss的deploy/jms目录下的uil2-service.xml文件中找到。

      2)  destination使用自定义的,需要在Jboss加一个配置文件,下面会介绍。

      3)  MessageProducer是消息发送方

      4)  MessageConsumer实现了一个MessageListener,监听是否收到消息。

 

3.  发送和接收消息的class如下:

 

MessageProducer.java

 

public class MessageProducer {

    private JmsTemplate template;

 

    private Destination destination;

 

    public void send(final String message) {

        template.send(destination, new MessageCreator() {

            public Message createMessage(Session session) throws JMSException {

                Message m = session.createTextMessage(message);

                return m;

            }

        });

    }

 

    public void setDestination(Destination destination) {

        this.destination = destination;

    }

 

    public void setTemplate(JmsTemplate template) {

        this.template = template;

    }

 

}

MessageConsumer.java

 

public class MessageConsumer implements MessageListener {

 

    public void onMessage(Message message) {

        System.out.println("****************************************");

        System.out.println(message);

    }

}

 

4.  写一个Servlet作为测试

 

JmsTest.java(不要忘记在web.xml中配置这个servlet哦!)

 

public class JmsTest extends HttpServlet {

 

    public void service(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        PrintWriter pw = response.getWriter();

        pw.println("<html>");

        pw.println("<head>");

        pw.println("</head>");

        pw.println("<body>");

        try {

            ServletContext servletContext = this.getServletContext();

            WebApplicationContext wac = WebApplicationContextUtils

                    .getRequiredWebApplicationContext(servletContext);

            MessageProducer mp = (MessageProducer) wac.getBean("messageProducer");

 

            mp.send("Message!!!!");

            pw.println("<h3>success</h3>");

        } catch (JmsException e) {

            pw.println(e);

        }

        pw.println("</body>");

        pw.println("</html>");

    }

 

}

5.  在Jboss的deploy/jms目录下创建sc-jms-service.xml

<?xml version="1.0" encoding="UTF-8"?>  

<server>  

    <mbean code="org.jboss.mq.server.jmx.Topic"  

         name="jboss.mq.destination:service=Topic,name=somcJms">  

        <depends optional-attribute-name="DestinationManager">

            jboss.mq:service=DestinationManager

        </depends>  

        <depends optional-attribute-name="SecurityManager">

            jboss.mq:service=SecurityManager

        </depends>  

        <attribute name="SecurityConf">  

            <security>  

                <role name="guest" read="true" write="true"/>  

                <role name="publisher" read="true" write="true" create="false"/>  

                <role name="durpublisher" read="true" write="true" create="true"/>  

            </security>  

        </attribute>  

    </mbean>  

</server>

6.  将工程达成war包直接放到Jboss的deploy目录下即可,然后启动Jboss访问JmsTest这个Servlet,你会在控制台看到接受到的消息,至此,一个最简单的Jms实例完成了

【上篇】
【下篇】

抱歉!评论已关闭.