Spring Boot 整合 JMS(ActiveMQ)
1. JMS简介
JMS (Java Message Service) 即Java消息服务,它通过统一JAVA API层面的标准,使得多个客户端可以通过JMS进行交互,大部分消息中间件提供商都对JMS提供支持。JMS和ActiveMQ的关系就象JDBC和JDBC驱动的关系。JMS包括两种消息模型:点对点和发布者/订阅者,同时JMS仅支持Java平台。
2. Spring Boot整合JMS
由于JMS是一套标准,因此Spring Boot整合JMS必然就是整合JMS的某一个实现,本案例以ActiveMQ为例来看Spring Boot如何进行整合。
2.1 添加依赖
首先编辑项目的 pom.xml 文件,添加 ActiveMQ 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2.2 配置 ActiveMQ
(1)首先在 application.properties 中配置 ActiveMQ 的连接信息:
# broker地址,默认端口是61616,只能写成tcp://
spring.activemq.broker-url=tcp://127.0.0.1:61616
# 信任所有的包,这个配置是为了支持发送对象消息
spring.activemq.packages.trust-all=true
# ActiveMQ的用户名
spring.activemq.user=admin
# ActiveMQ的密码
spring.activemq.password=admin
# queue和topic不能同时使用,使用topic的时候,把下面这行解除注释
#spring.jms.pub-sub-domain=true
(2)接着在项目配置类中提供两个消息队列 Bean(分别对应 Queue 和 Topic 这两种模式),这些 Bean 实例由 ActiveMQ 提供:Queue 模式与 Topic 模式主要区别就是是能否重复消费:
- Queue 为点对点模式:即使多个消费者,一个消息只会有一个消费者可以消费,消费后其它的消费者则不能消费此消息。当消费者不存在时,消息会一直保存,直到有消费消费。
- Topic 为发布订阅模式:允许多个消息消费者(订阅该 Topic)消费同一个消息。如果订阅者者不存在时,消息发出后也不会保存,直接丢失(不落地)
@Configuration
public class JmsConfig {
// Queue模式下的Destination
@Bean
public Queue queue(){
return new ActiveMQQueue("amq.queue");
}
// Topic模式下的Destination
@Bean
public Topic topic(){
return new ActiveMQTopic("amq.topic");
}
}
2.3 创建生产者
(1)这里我们使用 Spring 提供的 JMS 消息发送模版 JmsMessagingTemplate 进行消息发送,发送的是一个对象消息:
@RestController
public class ProducerController {
// JMS 消息发送模版
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Queue queue;
@Autowired
private Topic topic;
// 发送Queue消息
@GetMapping("/sendQueueMsg")
public void sendQueueMsg(Book book) {
this.jmsMessagingTemplate.convertAndSend(this.queue, book);
}
// 发送Topic消息
@GetMapping("/sendTopicMsg")
public void sendTopicMsg(Book book) {
this.jmsMessagingTemplate.convertAndSend(this.topic, book);
}
}
(2)这里发送的消息对象 Book 是一个普通的 JavaBean,具体代码如下:
@Data
@ToString
public class Book implements Serializable {
private Integer id;
private String name;
}
2.4 创建消费者
在方法上添加 @JmsListener 注解表示该方法是一个消息消费者,destination 参数表示消息消费者订阅的消息 destination:
@Component
public class Consumer {
// 监听和读取queue消息
@JmsListener(destination="amq.queue")
public void readActiveQueue(Book book) {
System.out.println("接收到queue消息:" + book);
}
// 监听和读取topic消息
@JmsListener(destination="amq.topic")
public void readActiveTopic(Book book) {
System.out.println("接收到topic消息:" + book);
}
}
3. 运行测试
3.1 Queue 模式
(1)启动项目,使用浏览器访问如下地址:
http://localhost:8080/sendQueueMsg?id=1&name=suohe
(2)可以看到控制台输出如下信息:
3.2 Topic 模式
(1)使用 Topic 模式时,我们需要先将 spring.jms.pub-sub-domain=true 这个配置放开:
(2)启动项目,使用浏览器访问如下地址:
http://localhost:8080/sendTopicMsg?id=2&name=wanghua
(3)可以看到控制台输出如下信息: