[JMS]java消息服务入门

来源:互联网 发布:win10右下角网络红叉 编辑:程序博客网 时间:2024/05/17 23:26

首先说一下什么是jms(java message service)java消息服务,Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于支持JAVA应用程序开发。在J2EE中,当两个应用程序使用JMS进行通信时,它们之间并不是直接相连的,而是通过一个共同的消息收发服务连接起来,可以达到解耦的效果,JMS天生就是异步的,客户端获取消息的时候,不需要主动发送请求,消息会自动发送给可用的客户端。(参考网上的)。
JMS对象模型有如下几种:
1. JMSConnectionFactory:JMS连接工厂,jms通过JDNI里面查找对应的连接工厂,然后通过连接工厂创建一个JMS连接。
2. JMS连接:很明显就是通过连接工厂创建的一个客户端和服务端的连接。
3. JMS会话:Session,表示连接客户端和服务器的回话连接,用该session可以创建不同的TextMessage类型,很重要,很重要,很重要。
4.JMS Destination: 也就说消息队列,准确的说应该是消息源。
5.JMS producer :消息的生产者,用来提供消息,这次的demo中我会使用JMSTemplate 模版来发送消息。
6. JMS consumer:消息的消费者,用来接收消息并消费消息,也是通过JMSTemplate receive()方法来接收消息。
JMS结构如下:
1. JMS provider:JMS提供者,例如(activeMQ,jbossMQ等)。
2. JMS客户:提供消息接收和发送的某一段程序,这个说起来有点抽象,就理解为一段代码就好了。
3. JMS 生产者,消费者,对应的就是消息的提供者和消息的使用者。
4. JMS消息队列:当然了包括了队列的基本性质,队头进入队尾取出,先进先出。
5. JMS Topic:就是消息的主题订阅,一次发布订阅,只要把连接对象设置为监听者,就能同时收到订阅消息。
6. JMS 消息对象:服务器和客户端进行传递的消息内容。
其中两种消息模型可用如下图表示(来自网络):
这幅图描述的是点对点的通信模型,主要有消息的发送者,消息队列,消息接收者,每个接收者只有一个消息队列,而且接收者和发送者之间没有绝对的时间依赖性,即使消息接收者不在运行,消息也能被收到,当接收者获得消息后,会再次发送一个消息确认通知给服务器。

                          图 1-1  点对点的通信队列模型 

另一种则是消息的发布&订阅模型,是一种一对多的关系。通过系统中的主题topic来保存消息和传递消息,匿名用户也可用发送消息 ,发布者和订阅者有着很强的时间依赖性,只有当客户端订阅以后,并且在运行状态才可以接收到订阅信息,为了减少这种时间上的依赖性,JMS允许客户端创建一个可持久化的订阅,这样即使客户端没有激活(为运行)也可接收到订阅信息。

这里写图片描述

             图 1-2  消息发布订阅模型

客户端在接收消息的时候有两种形式,一种是同步接收,另一种是异步接收,当订阅者使用receive方法接收,当消息未到达,该方法会阻塞,知道消息可用,另一种就是异步接收,客户端可创建一个消息监听器,当消息到达时,监听器会接收消息(方法为OnMessage()),并发送给订阅者。
测试部分结果如下:
这里写图片描述

测试topic:
这里写图片描述

请看代码:

1 pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>guo.mq.examples</groupId>  <artifactId>guo-mq02</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>guo-mq02</name>  <url>http://maven.apache.org</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.12</version>      <scope>test</scope>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>4.3.2.RELEASE</version>    </dependency>    <dependency>      <groupId>org.apache.activemq</groupId>      <artifactId>activemq-all</artifactId>      <version>5.11.0</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-jms</artifactId>      <version>4.1.4.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-test</artifactId>      <version>4.1.4.RELEASE</version>    </dependency>  </dependencies></project>

2 spring配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <context:component-scan base-package="com.activemq.queue.*" annotation-config="true"/>     <!--连接工厂 创建连接-->    <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">        <property name="brokerURL" value="tcp://localhost:61616"/>     </bean>     <!--队列1-->    <bean id="queueDestination1" class="org.apache.activemq.command.ActiveMQQueue">        <constructor-arg>            <value>queue1</value>        </constructor-arg>    </bean>    <!--消息模版-->    <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">        <property name="connectionFactory" ref="connectionFactory"/>        <property name="defaultDestination" ref="queueDestination1"/>        <property name="receiveTimeout" value="10000"/>    </bean>    <!--queue消息 生产者 -->    <bean id="producerService" class="com.activemq.queue.ProduceServiceImpl">        <property name="jmsTemplate" ref="JmsTemplate"/>    </bean>    <!--queue消息 消费者 -->    <bean id="consumerService" class="com.activemq.queue.ConsumerServiceImpl">        <property name="jmsTemplate" ref="JmsTemplate"></property>    </bean>    <!--队列2-->    <bean id="queueDetination2" class="org.apache.activemq.command.ActiveMQQueue">        <constructor-arg>            <value>queue2</value>        </constructor-arg>    </bean>    <bean id="messageListener" class="com.activemq.queue.QueueMessageLIstener"></bean>    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">        <property name="connectionFactory" ref="connectionFactory"/>        <property name="destination" ref="queueDetination2"/>        <property name="messageListener" ref="messageListener"/>    </bean>    <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">        <constructor-arg value="topicDestionation"/>    </bean>    <bean id="topicJmsTemplate" class="org.springframework.jms.core.JmsTemplate">        <property name="connectionFactory" ref="connectionFactory"/>        <property name="defaultDestination" ref="topicDestination"/>        <property name="pubSubDomain" value="true"/>        <property name="receiveTimeout" value="10000"/>    </bean>    <!--topic消息发布者 -->    <bean id="topicProvider" class="com.activemq.queue.TopicProvider">        <property name="topicJmstemplate" ref="topicJmsTemplate"></property>    </bean>    <!--topic消息监听者-->    <bean id="messageListener1" class="com.activemq.queue.TopicMessageListener"/>    <bean id="messageListener2" class="com.activemq.queue.TopicMessageListener2"/>    <!--topic消息监听容器-->    <bean id="topicJmsContainer"          class="org.springframework.jms.listener.DefaultMessageListenerContainer">        <property name="connectionFactory" ref="connectionFactory" />        <property name="destination" ref="topicDestination" />        <property name="messageListener" ref="messageListener1" />    </bean>    <!--topic消息监听容器-->    <bean id="topicJmsContainer2"          class="org.springframework.jms.listener.DefaultMessageListenerContainer">        <property name="connectionFactory" ref="connectionFactory" />        <property name="destination" ref="topicDestination" />        <property name="messageListener" ref="messageListener2" />    </bean>  <!--session队列-->    <bean id="sessionAwateQueue" class="org.apache.activemq.command.ActiveMQQueue">        <constructor-arg value="sseionAwareDestinationQueue"/>    </bean>    <!--消费者会话监听器-->    <bean id="ConsumerSessionAwareListener" class="com.activemq.queue.ConsumerSessionAwareListener">        <property name="destination" ref="queueDestination1"/>    </bean>     <!--消息监听容器-->    <bean id="sessionAwareListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">        <property name="connectionFactory" ref="connectionFactory"/>        <property name="destination" ref="sessionAwateQueue"/>        <property name="messageListener" ref="ConsumerSessionAwareListener"/>    </bean>    <bean id="adapterQueue" class="org.apache.activemq.command.ActiveMQQueue">        <constructor-arg value="adapterQueue"/>    </bean>    <!--消息监听适配器 自动回复消息-->    <bean id="jmsMessageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">        <property name="defaultListenerMethod" value="reveiverMessage"/>        <property name="delegate">            <bean class="com.activemq.queue.ConsumerListener"/>        </property>    </bean><!--消息是配置容器-->    <bean id="jmsMessageContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">        <property name="destination" ref="adapterQueue"/>        <property name="connectionFactory" ref="connectionFactory"/>        <property name="messageListener" ref="jmsMessageListenerAdapter"/>    </bean></beans>

3 ConsumerListener:

@Componentpublic class ConsumerListener {    public String reveiverMessage(String message)    {        System.out.println("ConsumerListener接收到一个Text消息:\t" + message);        return "consumerListener 回复你了";    }}

4 ConsumerServiceImpl:

@Componentpublic class ConsumerService {    private JmsTemplate jmsTemplate;    public void receive(Destination  destination) throws JMSException {        TextMessage textMessage = (TextMessage) jmsTemplate.receive(destination);        System.out.println("ConsumerService从"+destination.toString()+"获取消息"+textMessage.getText());    }}

5 ConsumerSessionAwareListener

@Componentpublic class ConsumerSessionAwareListener implements SessionAwareMessageListener<TextMessage> {    private Destination destination;    //  session 可以用来回复消息    public void onMessage(TextMessage textMessage, Session session) throws JMSException {        System.out.println("ConsumerListner 收到消息" +textMessage.getText());        // 发送消息        MessageProducer producer = session.createProducer(destination);        TextMessage textMessage1 = session.createTextMessage("Consumer 收到消息后给你回复了一条");        producer.send(textMessage1);    }    public void setDestination(Destination destination) {        this.destination = destination;    }}

6 ProduceServiceImpl

/** 1. Created by yangtianrui on 17/7/28. */@Componentpublic class ProduceServiceImpl implements ProducerService {    private JmsTemplate jmsTemplate;    public void sendMessage(final String msg) {        final String destionation = jmsTemplate.getDefaultDestinationName();        jmsTemplate.send(new MessageCreator() {            public Message createMessage(Session session) throws JMSException {                System.out.println("ProducerService向队列" +destionation + "发送了消息:\t" + msg);                return session.createTextMessage(msg);            }        });    }    public void sendMessage(final Destination destination, final String msg) {          jmsTemplate.send(destination, new MessageCreator() {              public Message createMessage(Session session) throws JMSException {                  System.out.println("ProducerService向队列" +destination.toString() + "发送了消息:\t" + msg);                  return session.createTextMessage(msg);              }          });    }    public void sendMessage(final Destination destination, final String msg, final Destination response) {        jmsTemplate.send(destination, new MessageCreator() {            public Message createMessage(Session session) throws JMSException {                System.out.println("ProducerService向队列" + destination.toString() + "发送了消息:\t" + msg);                TextMessage textMessage = session.createTextMessage(msg);                textMessage.setJMSReplyTo(response);                return textMessage;            }        });    }    public void setJmsTemplate(JmsTemplate jmsTemplate) {        this.jmsTemplate = jmsTemplate;    }}

7 QueueMesageListener

@Componentpublic class QueueMessageLIstener implements MessageListener {    public void onMessage(Message message) {        TextMessage textMessage = (TextMessage) message;        try {            System.out.println("MessageListener监听器监听到了"+textMessage.getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}

9 TopicMessageListener

@Componentpublic class TopicMessageListener implements MessageListener{    public void onMessage(Message message) {        TextMessage textMessage = (TextMessage) message;        try {            System.out.println("TopicMessageListener收到了您发布的主题"+textMessage.getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}

10 TopicMessageListener2

@Componentpublic class TopicMessageListener2 implements MessageListener{    public void onMessage(Message message) {        TextMessage textMessage = (TextMessage) message;        try {            System.out.println("TopicMessageListener2收到了您发布的主题"+textMessage.getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}

11 TopicProvider

@Componentpublic class TopicProvider {    private JmsTemplate topicJmstemplate;    public void sendMessage(final Destination destination, final String msg)    {        topicJmstemplate.send(destination, new MessageCreator() {            public Message createMessage(Session session) throws JMSException {                System.out.println("ProcuderServiceTopic发布了主题"+destination.toString()+".........."+msg);                return session.createTextMessage(msg);            }        });    }    public void setTopicJmstemplate(JmsTemplate topicJmstemplate) {        this.topicJmstemplate = topicJmstemplate;    }}

以下就是测试代码了:

import com.activemq.iqueue.ConsumerService;import com.activemq.iqueue.ProducerService;import com.activemq.queue.TopicMessageListener;import com.activemq.queue.TopicMessageListener2;import com.activemq.queue.TopicProvider;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.jms.Destination;/** * Created by yangtianrui on 17/7/28. */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:/spring-applicationcontext.xml")public class SpringMq_Test {    @Autowired    private ConsumerService consumerService;    @Autowired    private ProducerService producerService;    @Autowired    private Destination queueDestination1;    @Autowired    private Destination queueDetination2;    @Autowired    private Destination topicDestination;    @Autowired    @Qualifier("topicProvider")    private TopicProvider topicProvide;    @Autowired    private TopicMessageListener topicMessageListener;    @Autowired    private TopicMessageListener2 topicMessageListener2;    @Autowired    private Destination sessionAwateQueue;    @Autowired    private Destination adapterQueue;    @Test    public void test_senMessage()    {        producerService.sendMessage("hello queue1");    }    @Test    public void testProduce() {        String msg = "Hello queue1 !";        producerService.sendMessage(msg);    }   @Test    public void test_receive()   {       consumerService.receive(queueDestination1);   }    @Test    public void test_topic()    {    topicProvide.sendMessage(topicDestination,"topic.......");    }  @Test    public void test_adapter()    {        //queueDestination1        producerService.sendMessage(adapterQueue,"通知队列1获取消息",queueDestination1);        consumerService.receive(queueDestination1);   }   @Test    public void test_session()   {       producerService.sendMessage(sessionAwateQueue,"请队列1队列接收消息");       consumerService.receive(queueDestination1);   }}
原创粉丝点击