Spring 异步消息
异步消息简介
异步消息是一个应用程序向另一个应用程序间接发送消息的一种方式,这种方式无需等待对方的相应。
异步消息中有两个主要的概念:消息代理(message broker)和目的地(destination)。
当一个应用发送消息时,会将消息发送给一个消息代理。消息代理可以确保被投递到指定的目的地,同时解放发送者,使其能够继续进行其他的业务。
目的地只关注消息应该从哪里获得,而并不关心是谁取走了消息。有两种通用的目的地:队列(queue)和主题(topic),分别对应点对点模型和发布/订阅模型。
点对点模型:
在点对点模型中,每一条消息都只有一个发送者和接收者。可以理解为“生产者-消费者”模式。当消息代理得到消息时,它将消息放入一个队列中。当接收者请求队列中的下一条消息时,消息会从队列中取出,并投递给接收者。因为消息投递后会从队列中删除,这样就能保证每条消息只投递给一个接收者。
发布/订阅模型:
在发布/订阅消息模型中,消息会发送给一个主题。与队列相同,多个接收者都可以监视一个主题,但与队列不同的是,消息不再是只投递给一个接收者,而是所有的订阅者都会接收到此消息的副本。类似“观察者模式”。
异步消息的优点
同步消息 |
异步消息 |
---|---|
同步通信意味着等待 客户端通过服务接口与远程服务相耦合 客户端与远程服务的位置相耦合 客户端与服务的可用性相耦合 |
无需等待 面向消息和解耦 位置独立 确保投递 |
- 同步通信意味着等待
- 客户端通过服务接口与远程服务相耦合
- 客户端与远程服务的位置相耦合
- 客户端与服务的可用性相耦合
- 无需等待
- 面向消息和解耦
- 位置独立
- 确保投递
Spring 中使用JMS发送异步消息
Java消息服务(JMS)是一个Java标准,定义了使用消息代理的通用API。类似与JDBC为数据库操作提供的通用接口一样。但JMS同样也和JDBC一样每次使用需要写大量版式代码。
JmsTemplate是Spring提供的一个模板,通过该模板为JMS提供支持。使用JmsTemplate能够非常容易地在消息圣蚕房发送队列和订阅消息,在消费消息的哪一方也能非常容易地接收这些消息。
1 Spring 搭建消息代理
选取ActiveMQ作为异步消息的消息代理,ActiveMQ是一个很好的开源消息代理产品,在Spring中使用Active之前必须下载并启动其服务。
1.1 创建连接工厂
第一步是配置JMS连接工厂,让JMS知道如何连接到ActiveMQ。ActiveMQConnectionFactory是ActiveMQ自带的连接工厂,在Spring中可以如下配置(p:brokerURL可选,用来指定代理的URL):
<bean id="connectionFactory"
class="org.apache.activemq.spring.ActiveMQConnectionFactory"
p:brokerURL="tcp://localhost:61616"/>
1.2 声明消息目的地
目的地可以是队列,也可以是主题。不论是队列还是主题,都必须使用特定的消息代理实现类在Spring中配置目的地Bean。
声明ActiveMQ队列:
<bean id="queue"
class="org.apache.activemq.command.ActiveMQQueue"
c:_="test.queue"/>
声明ActiveMQ主题:
<bean id="topic"
class="org.apache.activemq.command.ActiveMQTopic"
c:_="test.topic"/>
2 使用JMS
2.1 配置JmsTemplate
为了使用JmsTemplate,需要在Spring的配置文件中将它声明为一个bean。配置方法如下:
<bean id="jmsTemplate"
class="org.springfarmework.jms.core.JmsTemplate"
c:_-ref="connectionFactory" />
2.2 发送消息
配置好JmsTemplate后,使用JmsOperation(JmsTemplate所实现的接口)将目标对象发送给消息队列,队列会在稍后得到处理。
2.2.1 send()方法实现
首先需要一个JMS对象,然后调用JMS的send方法即可实现发送异步消息。
注意:send()方法的第一个参数是目的地,1.2配置过的。第二个参数是MessageCreator类型的匿名对象,需要实现createMessage方法。
public class AlterService{
@Autowired
private JmsOperations jmsOperations; //注入JMS模板
public void sendString(String str){
jmsOperations.send( //调用方法发送消息
"test.queue", //指定目的地
new MessageCreator(){ //send方法需要一个MessageCreator作为参数,这里使用匿名类实现
public Message createMessage(Session session) throws JMSException{ //需要实现该方法
return session.createObjectMessage(string); //创建消息
}
}
);
}
}
2.2.2 设置默认目的地
2.2.1中send方法的第一个参数指定目的地,其实可以在配置JmsTemplate时指定默认目的地,这样就可以省去send的第一个参数。
<bean id="jmsTemplate"
class="org.springfarmework.jms.core.JmsTemplate"
c:_-ref="connectionFactory"
p:defaultDestinationName="test.queue" />
2.2.3 convertAndSend()方法实现
convertAndSend()方法并不需要MessageCreator参数,这是因为该方法会使用内置的消息转换器创建消息。所以使用convertAndSend()方法时代码非常简洁:
public void sendString(String string){
jmsOperations.converAndSend(string);
}
2.3 接收消息
接收消息比发送消息更为简单,只需要调用JmsTemplate的receice()方法即可。当调用该方法时。JmsTemplate会尝试从消息代理中获取一个消息。如果没有消息receice()方法会一直等待,知道获取方法为止。
public String receiceString(){
try{
return (String) jmsOperations.receive();
}catch (JMSException jmsException){
throw JmsUtils.convertJmsAccessException(jmsException);
}
}
- python访问http的GET/POST
- 用openssl库RSA加密解密
- Kobject浅析
- ASP.NET Core应用的错误处理[2]:DeveloperExceptionPageMiddleware中间件如何呈现“开发者异常页面”
- RSA简介(二)——模幂算法
- 为虚拟机vCPU绑定物理CPU
- RSA简介(三)——寻找质数
- RSA简介(四)——求逆算法
- 平方根的C语言实现(三) ——最终程序实现
- ASP.NET Core应用的错误处理[3]:ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”
- 【视频】Es6新特性-Symbol
- shell编程/字库裁剪(3)——验证
- 特征选择(Feature Selection)引言
- shell编程/字库裁剪(2)——编程过程
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 实现LRU算法
- 逻辑漏洞之无密码登录(vlcms)
- Python开发 常见异常和解决办法
- 约瑟夫问题
- AUC、ROC详解:原理、特点&算法
- akka-streams - 从应用角度学习:basic stream parts
- 多线程基础(四):volatile和可见性问题及happens-before原则
- 多线程基础(三):synchronized关键字及java内存模型简介
- 多线程基础(一): 线程概念及生命周期
- Windows下Redis服务的安装及Redis服务的命令行启动和关闭
- git hooks
- 二叉树的层次遍历 II
- Android开发笔记(一百七十三)给安装包APK文件瘦身
- 从 1 到 0 构建博客项目(1) -- 操作系统篇(1)
- Spring JPA 定义查询方法