二、Spring整合JMS(一)——基于ActiveMQ实现
四、Spring整合JMS(三)——MessageConverter消息转换器
在Spring整合JMS的应用中我们在定义消息监听器的时候一共可以定义三种类型的消息监听器,分别是MessageListener、SessionAwareMessageListener和MessageListenerAdapter。下面就分别来介绍一下这几种类型的区别。
1、MessageListener消息监听器
MessageListener是最原始的消息监听器,它是JMS规范中定义的一个接口。其中定义了一个用于处理接收到的消息的onMessage方法,该方法只接收一个Message参数。我们前面在讲配置消费者的时候用的消息监听器就是MessageListener,代码如下:
package cn.tzz.jms.activemq.spring; 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) { //这里我们知道生产者发送的就是一个纯文本消息,所以这里可以直接进行强制转换 TextMessage textMsg = (TextMessage) message; try { System.out.println("\t\t接收到消息:" + textMsg.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
2、SessionAwareMessageListener消息监听器
SessionAwareMessageListener是Spring为我们提供的,它不是标准的JMS MessageListener。MessageListener的设计只是纯粹用来接收消息的,假如我们在使用MessageListener处理接收到的消息时我们需要发送一个消息通知对方我们已经收到这个消息了,那么这个时候我们就需要在代码里面去重新获取一个Connection或Session。SessionAwareMessageListener的设计就是为了方便我们在接收到消息后发送一个回复的消息,它同样为我们提供了一个处理接收到的消息的onMessage方法,但是这个方法可以同时接收两个参数,一个是表示当前接收到的消息Message,另一个就是可以用来发送消息的Session对象。
实例:
在上面代码中我们定义了一个SessionAwareMessageListener,在这个Listener中我们在接收到了一个消息之后,利用对应的Session创建了一个到destination的生产者和对应的消息,然后利用创建好的生产者发送对应的消息。
接着我们在Spring的配置文件中配置该消息监听器将处理来自一个叫sessionAwareQueue的目的地的消息,并且往该MessageListener中通过set方法注入其属性destination的值为queueDestination。这样当我们的SessionAwareMessageListener接收到消息之后就会往queueDestination发送一个消息。
测试代码如下:
程序运行之后控制台输出如下:
生产者发消息:测试SessionAwareMessageListener
接收到消息:测试SessionAwareMessageListener
接收到消息:SessionAwareMessageListener........
这说明我们已经成功的往sessionAwareQueue发送了一条纯文本消息,消息会被ConsumerSessionAwareMessageListener的onMessage方法进行处理,在onMessage方法中ConsumerSessionAwareMessageListener就是简单的把接收到的纯文本信息的内容打印出来了,之后再往queueDestination发送了一个纯文本消息,消息内容是“ConsumerSessionAwareMessageListener…”,该消息随后就被ConsumerMessageListener处理了,根据我们的定义,在ConsumerMessageListener中也只是简单的打印了一下接收到的消息内容。
3、MessageListenerAdapter
MessageListenerAdapter类实现了MessageListener接口和SessionAwareMessageListener接口,它的主要作用是将接收到的消息进行类型转换,然后通过反射的形式把它交给一个普通的Java类进行处理。
MessageListenerAdapter会把接收到的消息做如下转换:
TextMessage转换为String对象;
BytesMessage转换为byte数组;
MapMessage转换为Map对象;
ObjectMessage转换为对应的Serializable对象。
既然前面说了MessageListenerAdapter会把接收到的消息做一个类型转换,然后利用反射把它交给真正的目标处理器——一个普通的Java类进行处理(如果真正的目标处理器是一个MessageListener或者是一个SessionAwareMessageListener,那么Spring将直接使用接收到的Message对象作为参数调用它们的onMessage方法,而不会再利用反射去进行调用),那么我们在定义一个MessageListenerAdapter的时候就需要为它指定这样一个目标类。这个目标类我们可以通过MessageListenerAdapter的构造方法参数指定,如:
接下来我们来看一个示例,假设我们有一个普通的Java类ConsumerListener,其对应有两个方法,handleMessage和receiveMessage,其代码如下:
假设我们要把它作为一个消息监听器来监听发送到adapterQueue的消息,这个时候我们就可以定义一个对应的MessageListenerAdapter来把它当做一个MessageListener使用。
<!-- 消息监听器 .3--> <bean id="adapterQueue" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>adapterQueue</value> </constructor-arg> </bean> <!-- 消息监听适配器 --> <bean id="messageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"> <property name="delegate"> <bean class="cn.tzz.jms.activemq.spring.listener.ConsumerListener"/> </property> <!-- 也可以上述方式配置,也可通过它的delegate属性来指定,如下 --> <!-- <constructor-arg> --> <!-- <bean class="cn.tzz.jms.activemq.spring.listener.ConsumerListener"/> --> <!-- </constructor-arg> --> <property name="defaultListenerMethod" value="receiveMessage"/> </bean> <!-- 消息监听适配器对应的监听容器 --> <bean id="messageListenerAdapterContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory"/> <property name="destination" ref="adapterQueue"/> <property name="messageListener" ref="messageListenerAdapter"/><!-- 使用MessageListenerAdapter来作为消息监听器 --> </bean>
测试代码如下:
运行测试程序控制台输出如下:
生产者发消息:测试MessageListenerAdapter
ConsumerListener通过receiveMessage接收到消息:测试MessageListenerAdapter
MessageListenerAdapter除了会自动的把一个普通Java类当做MessageListener来处理接收到的消息之外,其另外一个主要的功能是可以自动的发送返回消息。
当我们用于处理接收到的消息的方法的返回值不为空的时候,Spring会自动将它封装为一个JMS Message,然后自动进行回复。那么这个时候这个回复消息将发送到哪里呢?这主要有两种方式可以指定。
第一,可以通过发送的Message的setJMSReplyTo方法指定该消息对应的回复消息的目的地。这里我们把我们的生产者发送消息的代码做一下修改,在发送消息之前先指定该消息对应的回复目的地为一个叫responseQueue的队列目的地,具体代码如下所示:
接着定义一个叫responseQueue的队列目的地及其对应的消息监听器和监听容器。
ResponseQueueListener的定义如下所示:
运行上述测试代码之后,控制台输出如下:
生产者发送消息:测试MessageListenerAdapter
ConsumerListener通过receiveMessage接收到消息:测试MessageListenerAdapter
接收到发送到responseQueue的一个消息这是ConsumerListener对象的receiveMessage方法的返回值。
这说明我们的生产者发送消息被MessageListenerAdapter处理之后,MessageListenerAdapter确实把监听器的返回内容封装成一个Message往原Message通过setJMSReplyTo方法指定的回复目的地发送了一个消息。对于MessageListenerAdapter对应的监听器处理方法返回的是一个null值或者返回类型是void的情况,MessageListenerAdapter是不会自动进行消息的回复的,有兴趣的网友可以自己测试一下。
第二,通过MessageListenerAdapter的defaultResponseDestination属性来指定。这里我们也来做一个测试,首先维持生产者发送消息的代码不变,即发送消息前不通过Message的setJMSReplyTo方法指定消息的回复目的地;接着我们在定义MessageListenerAdapter的时候通过其defaultResponseDestination属性指定其默认的回复目的地是“defaultResponseQueue”,并定义defaultResponseQueue对应的消息监听器和消息监听容器。
DefaultResponseQueueListener的代码如下所示:
这时候运行如下测试代码:
@Test public void testMessageListenerAdapter() { producerService.sendMessage(adapterQueue, "测试MessageListenerAdapter"); }
控制台将输出如下内容:
生产者发送消息:测试MessageListenerAdapter
ConsumerListener通过receiveMessage接收到消息:测试MessageListenerAdapter
DefaultResponseQueueListener接收到发送到defaultResponseQueue的一个息:这是ConsumerListener对象的receiveMessage方法的返回值。
这说明MessageListenerAdapter会自动把真正的消息处理器返回的非空内容封装成一个Message发送回复消息到通过defaultResponseDestination属性指定的默认消息回复目的地。
既然我们可以通过两种方式来指定MessageListenerAdapter自动发送回复消息的目的地,那么当我们两种方式都指定了而且它们的目的地还不一样的时候会怎么发送呢?是两个都发还是只发其中的一个呢?关于这部分的测试我这里就不赘述了,有兴趣的网友可以自己进行。这里我可以直接的告诉大家,当两种方式都指定了消息的回复目的地的时候使用发送消息的setJMSReplyTo方法指定的目的地将具有较高的优先级,MessageListenerAdapter将只往该方法指定的消息回复目的地发送回复消息。
相关推荐
本篇文章将详细探讨如何通过Spring框架整合JMS,特别是使用ActiveMQ作为消息代理来实现消息的收发功能。 首先,我们需要理解Spring对JMS的支持。Spring提供了`org.springframework.jms`包,包含了一系列接口和类,...
本文将深入探讨如何在Spring中整合JMS并实现事务管理,以确保消息传递的可靠性和一致性。 首先,我们需要理解Spring的声明式事务管理。Spring提供了一种强大的声明式事务管理机制,它允许我们在不编写任何事务控制...
Spring提供了对JMS的全面支持,包括连接工厂配置、消息生产者、消费者以及消息转换器等。JMS允许应用程序通过消息中间件进行解耦通信,提高系统的可扩展性和可靠性。Spring JMS抽象了JMS API,提供了更易于使用的...
此外,Spring还支持JMS监听器容器,使得消息的消费可以以非阻塞的方式进行,提高了系统的可扩展性和并发性能。 接下来,我们来看看如何集成ActivemQ。首先,需要在项目中引入ActivemQ的相关依赖,通常是在pom.xml...
此外,通过Spring的配置文件或Java配置,可以定义消息监听器(MessageListener),以便在接收到消息时执行相应的业务逻辑。 六、案例分析与实践建议 在实际开发中,结合Spring Boot的特性,可以进一步简化JMS与...
在Java世界中,ActiveMQ和Spring的整合是企业级应用中常见的消息中间件解决方案,用于实现JMS(Java Message Service)消息传递。本教程将深入探讨如何将这两个强大的工具结合在一起,以创建一个简单的发送JMS消息的...
本示例“spring boot整合JPA——demo”将演示如何在Spring Boot项目中配置和使用JPA。 首先,我们需要理解Spring Boot与JPA的关系。Spring Boot是基于Spring框架的快速开发工具,它通过自动化配置减少了常规设置...
在具体实践中,我们需要在`applicationContext.xml`中配置JMS连接工厂、目的地(队列或主题)、以及消息监听器。然后,创建消息生产者和消费者类,分别调用`JmsTemplate.send()`方法发送消息,和重写`onMessage()`...
在Spring和JMS整合后的应用中,可以使用JmsTemplate类来发送消息,或者注册消息监听器来处理接收到的消息。发布消息时,只需调用JmsTemplate的send方法并指定目的地即可。消息的监听通常通过实现了MessageListener...
精通Eclipse整合Web开发——Struts,Spring,Hibernate,JBPM 图书馆下载的,不是很清晰,如果介意的,请不要下载,不要拍砖。 总共有三部分。
- **MessageListenerContainer**:通过实现`MessageListener`接口,Spring容器会自动启动监听线程,接收到消息后调用监听器方法。 - **JmsTemplate.receive()**:阻塞式接收,调用后会等待直到有消息到达。 **7. ...
- **Spring JMS模块**:Spring框架提供了一组JMS模板和监听器容器,简化了消息的生产和消费。 - **ConnectionFactory**:JMS API的核心对象,用于创建连接到消息代理的连接。 - **Destination**:表示消息的目的...
【ActiveMQ和Spring整合JMS】的文档主要介绍了消息中间件的基本概念,特别是重点讨论了ActiveMQ和JMS的相关知识。消息中间件是用于不同分布式系统之间数据交流的工具,通过消息传递机制来扩展进程间的通信。ActiveMQ...
Spring还允许创建消息驱动的POJO(Plain Old Java Object),这是一种简单的消息监听器实现,无需扩展特定接口。只需在POJO上添加`@JmsListener`注解即可。 ```java @Service public class MDPService { @...
7. **消息驱动的POJO(MDP)**:Spring支持消息驱动的POJO,这是一种轻量级的监听器模式,使得任何实现了`MessageListener`的类都可以作为消息消费者。 在实际项目中,基于Spring的JMS编程可以帮助我们构建可扩展、...
JMS 支持两种消息传递模型: 点对点(point-to-point,简称 PTP) 发布/订阅(publish/subscribe,简称 pub/sub)。 这两种消息传递模型非常相似,但有以下区别: PTP 消息传递模型规定了一条消息只能传递给一个接收...
在Spring的配置文件(如applicationContext.xml)中,我们需要配置JMS连接工厂、目的地(Topic或Queue)以及消息监听器容器。 ```xml <bean id="jmsTemplate" class="org.springframework.jms.core....
Spring 整合 JMS 实现同步收发消息(基于 ActiveMQ 的实现) Spring 整合 JMS 实现同步收发消息是指在 Spring 框架下使用 JMS(Java Message Service)协议来实现消息的同步收发。JMS 是一个基于 Java 的消息服务 ...
Spring-JMS是Spring框架的一部分,专门用于处理Java消息服务(JMS)的集成。这个jar包,即`spring-jms-3.1.1.RELEASE.jar`,包含了Spring对JMS API的抽象和扩展,使得在Spring应用中使用JMS变得更加简单和灵活。 **...