SpringBoot2.x整合ActiveMQ实战之点对点消息
1、官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-activemq
2、加入依赖
<!-- 整合消息队列ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
但是这样启动会报错,这是由于springboot版本引起的
ActiveMQConnectionFactoryConfiguration.PooledConnectionFactoryConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.messaginghub.pooled.jms.JmsPoolConnectionFactory' (OnClassCondition)
ActiveMQConnectionFactoryConfiguration.SimpleConnectionFactoryConfiguration:
出现了没有找到jmsTemplate
组件的错误。
查了网上各种出现此错误的解决办法,都是手动创建connectionFactory并创建JmsTemplate相关Bean对象。但是这种方式治标不治本。既然spring boot官方有整合ActiveMQ的相关方法,不可能会要求用户自己手动去创建相关的Bean对象的。此处个人进行了相关的分析并给出了对应解决办法:
由于spring boot自动配置该内部类的条件是类路径下必须存在JmsPoolConnectionFactory和PooledObject
两个类。
查看了依赖包中并未找到JmsPoolConnectionFactory
该类,从日志信息上看到该类应该存放于org.messaginghub.pooled.jms
包下的。但是我们依赖中并未引入相关的依赖包。从maven中央仓库中查询了该包的前缀org.messaginghub
发现该依赖是在PooledJMS Library
下的。然后尝试引入该maven依赖并去掉原来的ActiveMQ Pool
依赖:
引入新的包如下:
<!-- 整合消息队列ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.messaginghub</groupId>
<artifactId>pooled-jms</artifactId>
</dependency>
3、application.properties配置文件配置
#整合jms测试,安装在别的机器,防火墙和端口号记得开放
spring.activemq.broker-url=tcp://127.0.0.1:61616
#集群配置
#spring.activemq.broker-url=failover:(tcp://localhost:61616,tcp://localhost:61617)
spring.activemq.user=admin
spring.activemq.password=admin
#默认是缓存了jms的session的,所以主程序发送完消息后,不会退出,改为false主程序才可以退出 从SpringBoot2.1.0以后新增的
spring.jms.cache.enabled=false
4、在SpringBoot启动类中添加@EnableJms,开启支持jms,此处注入了bean,方便后面使用
在activeMQ中先创建一个队列common.queue如下
5、模拟请求
业务层如下:
package net.xdclass.base_project.service;
import javax.jms.Destination;
/**
* 功能描述:消息生产
* @author wq
*/
public interface ProducerService {
//指定消息队列和消息
public void sendMessage(Destination destination, final String message);
//使用默认消息队列发送消息
public void sendMessage(final String message);
}
实现类:
package net.xdclass.base_project.service.impl;
import javax.jms.Destination;
import javax.jms.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import net.xdclass.base_project.service.ProducerService;
@Service
public class ProducerServiceImpl implements ProducerService{
@Autowired
private JmsMessagingTemplate jmsTemplate;//用来发送消息到broker的对象
@Autowired
private Queue queue;
//使用默认队列(启动类中声明的queue,此处注入的queue)发送消息,message是待发送的消息
@Override
public void sendMessage(String message) {
jmsTemplate.convertAndSend(this.queue, message);
}
//发送消息,destination是发送到的队列,message是待发送的消息
@Override
public void sendMessage(Destination destination, String message) {
jmsTemplate.convertAndSend(destination, message);
}
}
一种是发送到指定的队列,一种是发送到默认的队列
控制器如下:
package net.xdclass.base_project.controller;
import javax.jms.Destination;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.xdclass.base_project.domain.JsonData;
import net.xdclass.base_project.service.ProducerService;
/**
* 功能描述:模拟微信支付回调接口
* @param msg 支付信息
* @return
*/
@RestController
@RequestMapping("/api/v1")
public class OrderController {
@Autowired
private ProducerService producerService;
@GetMapping("/order")
public Object order(String msg){
//生成消息队列地址
Destination destination = new ActiveMQQueue("order.queue");
producerService.sendMessage(destination, msg);
return JsonData.buildSuccess();
}
@GetMapping("/common")
public Object common(String msg){
producerService.sendMessage(msg);
return JsonData.buildSuccess();
}
}
在浏览器中访问如下:
activiteMQ中新产生了一个队列
6、消费者:实时监听对应的队列
package net.xdclass.base_project.jms;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class OrderConsumer {
@JmsListener(destination = "order.queue")//要监听的队列(实时监听)
public void receiveQueue(String text){
System.out.println("OrderConsumer收到的报文为:" + text);
}
}
控制台输出如下:
OrderConsumer收到的报文为:12312321321312
-----------------------------------------------------------
默认队列发送类似:
package net.xdclass.base_project.jms;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class CommonConsumer {
@JmsListener(destination = "common.queue")//要监听的队列(实时监听)
public void receiveQueue(String text){
System.out.println("CommonConsumer收到的报文为:" + text);
}
}
浏览器访问如下:
activeMQ中显示如下:
控制台输出如下:
CommonConsumer收到的报文为:默认队列knndasn