[概念解说]
JMS简介
JMS是一种与厂商无关的 API,用来访问消息收发系统消息。它类似于JDBC(Java DataBaseConnectivity),也类似于JPA(Java Persistence Api),JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。
JMS四个重要部分
- 消息主题(Topic),需要一个固定的主题,例如大家都是在谈论外卖,那主题就是外卖,别人讨论其他的跟你无关。
- 消息队列(MQ) ,存放或者实现JMS的功能,需要用到队列,有人放入消息到外卖队列,有人从外卖队列读取消息,就是一个消息队列的模型。
- 发送者(Sender),通过什么事或者想做什么事,就发个信息,例如点个外卖呗。
- 接收者(Receiver),然后外卖员就收到信息,办事。
MQ简介
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。
JMS和MQ的关系
- JMS是一个用于提供消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程。
- MQ则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的服务提供者。
那么这个问题就可以理解为:JMS是规范标准,MQ是其中一种有力的实现方式。
ActiveMQ
目前支持JMS的开源MQ,目前选择比较多,支持比较多的是ActiveMQ。还有阿里的RocketMQ,RabbitMQ等等。
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
[实战部分]
Maven配置
本文是参考Spring官方Jms的文章进行学习、整理以及改进
https://spring.io/guides/gs/messaging-jms/
主要用到的JMS核心包如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
Java配置文件
JmsConfig.java
@EnableJms
@Configuration
public class JmsConfig {
@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
return factory;
}
@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
Receiver接收者
只要有发送者发送了消息到”mailbox”这个主题(Topic),接收者就会调用这块逻辑。
@Component
public class Receiver {
@JmsListener(destination = "mailbox", containerFactory = "myFactory")
public void receiveMessage(Email email) {
System.out.println("Received <" + email + ">");
}
}
Sender发送者
主动权在你手里,尽情发送吧,”mailbox”为订阅的主题,至于Email里面有什么,似乎不是特别重要,只是一个普通的POJO,换成User什么的都没问题。
@RestController
public class TestController {
@Autowired
private JmsTemplate jmsTemplate;
/**
* 发送订阅
*/
@GetMapping("/email/send")
public Email updateItem(Email item) {
jmsTemplate.convertAndSend("mailbox", new Email("[email protected]", "Hello"));
return item;
}
}
[运行结果]
//本地调用Controller里面的内容,进行消息发送,这时候Receiver就会收到消息啦
http://localhost:1111/jms/email/send
//控制台输出
Received <Email{to=info@example.com, body=Hello}>
开源项目
https://github.com/moshowgame/spring-cloud-study/tree/master/spring-cloud-study-jms
https://github.com/moshowgame/spring-cloud-study/
https://gitee.com/moshow/spring-cloud-study
↑ github+gitee同步更新