[JMS]java消息服务入门

首先说一下什么是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:

@Component
public class ConsumerListener {

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

4 ConsumerServiceImpl:

@Component
public 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

@Component
public 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.
 */
@Component
public 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

@Component
public 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

@Component
public 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

@Component
public 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

@Component
public 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);
   }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值