JMS 消息队列接口基本使用指南

本文详细介绍了Java消息服务(JMS)的概念、体系结构、核心组件如JMS提供者、消费者和对象模型,以及如何在Spring框架中使用MessageListener和SessionAwareMessageListener。此外,还展示了如何在SpringBoot中集成JMS并配置相关组件以实现消息的发送和接收。

概述

介绍

JMS(Java Message Service)即 Java 消息服务应用程序接口,是一个 Java 平台中关于面向消息中间件(MOM)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java 消息服务是一个与具体平台无关的 API,绝大多数 MOM 提供商都对JMS 提供支持。

简短来说,JMS 是一种与厂商无关的 API,是 sun 公司为了统一厂商的接口规范,而定义出的一组api接口,用来访问消息收发系统消息。它类似于 JDBC(Java Database Connectivity),提供了应用程序之间异步通信的功能。


JMS 体系结构

  • JMS 提供者(JMS 的实现者,比如 activemq、jbossmq、tonglinkmq 等)
  • JMS 客户(使用提供者发送消息的程序或对象,例如在 12306 中,负责发送一条购票消息到处理队列中,用来解决购票高峰问题,那么,发送消息到队列的程序和从队列获取消息的程序都叫做客户)
  • JMS 生产者(producer、sender):负责创建并发送消息的客户
  • JMS 消费者(customer、listener):负责接收并处理消息的客户
  • JMS 消息(message):在 JMS 客户之间传递数据的对象
  • JMS 队列(queue):一个容纳那些被发送的等待阅读的消息的区域
  • JMS 主题(topic):一种支持发送消息给多个订阅者的机制

JMS 对象模型

  • 连接工厂(connectionFactory)客户端使用 JNDI 查找连接工厂,然后利用连接工厂创建一个 JMS 连接
  • JMS 连接:表示 JMS 客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的
  • JMS 会话:session 标识 JMS 客户端和服务端的会话状态。会话建立在 JMS 连接上,标识客户与服务器之间的一个会话进程。
  • JMS 目的(Destination): 又称为消息队列,是实际的消息源
  • 生产者和消费者
  • 消息类型:分为队列类型(优先先进先出)以及订阅类型

消息监听器

MessageListener

MessageListener 是最原始的消息监听器,它是 JMS 规范中定义的一个接口。其中定义了一个用于处理接收到的消息的 onMessage() 方法,该方法只接收一个 Message 参数。

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class ConsumerMessageListener implements MessageListener {
   
   
    public void onMessage(Message message) {
   
   
        // 若生产者发送的是一个纯文本消息,可以直接进行强制转换,或者直接把onMessage方法的参数改成Message的子类TextMessage
        TextMessage textMsg = (TextMessage) message;
        System.out.println("接收到一个纯文本消息。");
        try {
   
   
            System.out.println("消息内容是:" + textMsg.getText());
        } catch (JMSException e) {
   
   
            e.printStackTrace();
        }
    }
}

SessionAwareMessageListener

SessionAwareMessageListener 是 Spring 提供的,它不是标准的 JMS MessageListener。

MessageListener 的设计只是纯粹用来接收消息的,假如在使用 MessageListener 处理接收到的消息时需要发送一个消息通知对方已经收到这个消息了,那么这个时候就需要在代码里面去重新获取一个 Connection 或 Session。而 SessionAwareMessageListener 的设计就是为了方便在接收到消息后发送一个回复的消息,它同样提供了一个处理接收到的消息的 onMessage() 方法,但是这个方法可以同时接收两个参数,一个是表示当前接收到的消息Message,另一个就是可以用来发送消息的 Session 对象。

使用 SessionAwareMessageListener 监听器,可以在监听并消费了消息后,不用重新获取一个 Connection 或 Session,而是直接向原 Connection 或 Session 的某一个队列发送消息。

代码示例:

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.springframework.jms.listener.SessionAwareMessageListener;

public class ConsumerSessionAwareMessageListener implements SessionAwareMessageListener {
   
   
    private Destination destination;
    
    public void onMessage(TextMessage message, Session session) throws JMSException {
   
   
        System.out.println("收到一条消息");
        System.out.println("消息内容是:" + message.getText());
        
        MessageProducer producer = session.createProducer(destination);
        Message textMessage = session.createTextMessage("ConsumerSessionAwareMessageListener。。。");
        producer.send(textMessage);
    }
    
    public Destination getDestination() {
   
   
        returndestination;
    }
    
    public void setDestination(Destination destination) {
   
   
        this.destination = destination;
    }
}

说明:定义了一个 SessionAwareMessageListener,在这个 Listener 中在接收到了一个消息之后,利用对应的 Session 创建了一个到 destination 的生产者和对应的消息,然后利用创建好的生产者发送对应的消息。


MessageListenerAdapter

MessageListenerAdapter 类实现了 MessageListener 接口和 SessionAwareMessageListener 接口,它的主要作用是将接收到的消息进行类型转换,然后通过反射的形式把它交给一个普通的 Java 类进行处理。

  • MessageListenerAdapter 会把接收到的消息做如下转换:

    • TextMessage 转换为 String 对象
    • BytesMessage 转换为 byte 数组
    • MapMessage 转换为 Map 对象
    • ObjectMessage 转换为对应的 Serializable 对象

    代码示例:

    // 目标处理器类
    public class ConsumerListener {
         
           
        public void handleMessage(String message) {
         
           
            System.out.println("ConsumerListener通过handleMessage接收到一个纯文本消息,消息内容是:" + message);  
        }  
        public void receiveMessage(String message) {
         
           
            System.out.println("ConsumerListener通过receiveMessage接收到一个纯文本消息,消息内容是:" + message
Classes contained in javax.jms.jar: javax.transaction.xa.XAResource.class javax.jms.BytesMessage.class javax.jms.Message.class javax.jms.JMSException.class javax.jms.Destination.class javax.jms.DeliveryMode.class javax.jms.Connection.class javax.jms.Session.class javax.jms.ConnectionMetaData.class javax.jms.ExceptionListener.class javax.jms.ServerSessionPool.class javax.jms.ConnectionConsumer.class javax.jms.Topic.class javax.jms.MapMessage.class javax.jms.ObjectMessage.class javax.jms.StreamMessage.class javax.jms.TextMessage.class javax.jms.MessageListener.class javax.jms.MessageProducer.class javax.jms.MessageConsumer.class javax.jms.Queue.class javax.jms.TopicSubscriber.class javax.jms.QueueBrowser.class javax.jms.TemporaryQueue.class javax.jms.TemporaryTopic.class javax.jms.ServerSession.class javax.jms.ConnectionFactory.class javax.jms.MessageNotReadableException.class javax.jms.MessageNotWriteableException.class javax.jms.QueueConnection.class javax.jms.QueueSession.class javax.jms.QueueReceiver.class javax.jms.QueueSender.class javax.jms.QueueConnectionFactory.class javax.jms.QueueRequestor.class javax.jms.TopicConnection.class javax.jms.TopicSession.class javax.jms.TopicPublisher.class javax.jms.TopicConnectionFactory.class javax.jms.TopicRequestor.class javax.jms.XAConnection.class javax.jms.XASession.class javax.jms.XAConnectionFactory.class javax.jms.XAQueueConnection.class javax.jms.XAQueueSession.class javax.jms.XAQueueConnectionFactory.class javax.jms.XATopicConnection.class javax.jms.XATopicSession.class javax.jms.XATopicConnectionFactory.class javax.jms.MessageEOFException.class javax.jms.TransactionRolledBackException.class javax.jms.MessageFormatException.class javax.jms.IllegalStateException.class javax.jms.JMSSecurityException.class javax.jms.ResourceAllocationException.class javax.jms.TransactionInProgressException.class javax.jms.InvalidDestinationException.class javax.jms.InvalidClientIDException.class javax.jms.InvalidSelectorException.class
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨鸦_Cormorant

大家喜欢的话可以点个关注投币哟

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值