【Spring】使用Spring和AMQP发送接收消息(下)

为什么80%的码农都做不了架构师?>>>   hot3.png

上篇讲了RabbitMQ连接工厂的作用是用来创建RabbitMQ的连接,本篇就来讲讲RabbitMQ的发送消息。通过RabbitMQ发送消息最简单的方式就是将connectionFactory Bean注入到服务层类中,并使用它创建Connection,使用这个Connection来创建Channel,再使用这个Channel发布消息到Exchange中。

当然Spring AMQP提供了RabbitTemplate来简便我们的操作,消除RabbitMQ发送和接收消息相关的样板代码。使用RabbitTemplate也是先在配置文件中写相关的配置,使用Rabbit命名空间的<template>元素,如下:

<template id="rabbitTemplate" connection-factory="connectionFactory">

现在要发送消息只需要将模板bean注入到服务层类中(这里以SendServiceImpl为例),并使用它来发送Spittle,使用RabbitTemplate来发送Spittle提醒,代码如下:

public class SendServiceImpl implements SendService {private RabbitTemplate rabbit;@Autowiredpublic SendServiceImpl (RabbitTemplate rabbit) {this.rabbit = rabbit;}public void sendSpittle (Spittle spittle) {rabbit.convertAndSend("spittle.test.exchange", "spittle.test", spittle);}
}

上面代码中sendSpittle()调用RabbitTemplate的convertAndSend()方法,传入的三个参数分别是Exchange的名称、routing key以及要发送的对象。
这里如果使用最简单的只传要发送的对象的重载方法,RabbitTemplate就使用默认的Exchange和routing key。按之前配置的话,这两项默认都为空,也可以自行在<template>元素上借助exchange和routing-key属性配置不同的默认值:

<template id="rabbitTemplate" connection-factory="connectionFactory"exchange="spittle.test.exchange" routing-key="spittle.test" />

此外RabbitTemplate还有其他方法可以用来发送消息,比如用send()方法来发送org.springframework.amqp.core.Message对象,如下所示:

Message message = new Message("Hello World".getBytes(), new MessageProperties());
rabbit.send("hello.exchange", "hello.routing", message);

使用send()方法的技巧在于构造要发送的Message对象,在上面的例子中,通过给定字符串的字节数组来构建Message实例。这里是字符串相对比较简单,如果消息是复杂对象的话,则会比较复杂。也是因为这样,所以一般会用convertAndSend()方法,它会自动将对象转换为Message,不过它需要一个消息转换器来帮助完成该任务,默认的转换器是SimpleMessageConverter,它适用于String、Serializable实例和字节数组。

发送消息完后,接下来就是接收消息了。
在传统JMS中有两种从队列获取信息的方式,使用JmsTemplate的同步方式以及使用消息驱动pojo的异步方式。Spring AMQP也提供了类似的方式来获取通过AMQP发送的消息。

使用RabbitTemplate来接收消息

RabbitTemplate提供的接收信息的方法中最简单的就是receive()方法,通过该方法就可以从队列中获取一个Message对象:

Message message = rabbit.receive("spittle.test.queue");

或者也可以通过配置获取消息的默认队列,这是通过在配置模板的时候,设置queue属性实现的:

<template id="rabbitTemplate" connection-factory="connectionFactory"exchange="spittle.test.exchange" routing-key="spittle.test" queue="spittle.test.queue" />

这样的话,在调用receive()方法时,不需要设置任何参数就能从默认队列中获取消息:

Message message = rabbit.receive( );

获取到Message对象后,一般需要将它的body属性中的字节数组转换为想要的对象,就像在发送的时候将领域对象转换为Message一样,将接收到的Message转换为领域对象也很繁琐。这里可以考虑使用RabbitTemplate的receiveAndConvert()方法作为替代方案:

Spittle spittle = (Spittle) rabbit.receiveAndConvert("spittle.test.queue");

receiveAndConvert()方法会使用与sendAndConvert()方法相同的消息转换器,将Message对象转换为原始的类型。
调用receive()和receiveAndConvert()方法都会立即返回,如果队列中没有等待的消息,将会得到null。这时一般需要程序员自己管理轮询以及必要的线程,实现队列监控。如果不想每次都同步轮询等待消息到达,可以使用Spring AMQP提供的消息驱动pojo,下面就看看使用消息驱动pojo的方式来接收消息。

使用消息驱动pojo来接收消息

如果想要在消息驱动pojo中异步地消费使用Spittle对象,先要解决这个pojo本身,如下的SpittleTestHandler扮演了这个角色:

public class SpittleTestHandler {public void handleSpittleTest (Spittle spittle) {...}
}

其实这个类并没有依赖于AMQP,不管通过什么机制传递过来Spittle对象,它都能够处理。
这里还需要在Spring应用上下文中将SpittleTestHandler声明为一个bean:

<bean id="spittleListener"class="com.***.spittr.test.SpittleTestHandler">

最后要声明一个监听器容器和监听器,当消息到达的时候,能够调用SpittleTestHandler,配置如下:

<listener-container connection-factory="connectionFactory"><listener ref="spittleListener" method="handleSpittleTest"queue-names="spittle.test.queue" />
</listener-container>

上面的<listener-container>与<listener>元素都来自rabbit命名空间。并通过queue-names属性来指定要监听的队列,这里只设定了一个要监听的队列,如果要设置多个队列的话,用逗号隔开。到这里消息接收就完成了,拿到消息后就可以在相应方法里执行相应处理了,使用AMQP发送接收消息就讲解到此了。

转载于:https://my.oschina.net/hin911/blog/862645

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软u盘安装工具_使用微软Winget工具安装软件教程

对于系统管理员来说&#xff0c;一款好用的软件包管理工具可以大大提高安装、部署、管理软件的效率。可之前只有 MscOS 和 Linux 官方才有软件包管理工具&#xff0c;微软官方现在终于为Windows系统发布了一款名为Winget的软件包管理工具&#xff0c;MS酋长下面就来为大家演示一…

RandomForestClassifier(随机森林检测每个特征的重要性及每个样例属于哪个类的概率)...

#In the next recipe, well look at how to tune the random forest classifier. #Lets start by importing datasets:from sklearn import datasets X, y datasets.make_classification(1000)# X(1000,20) #y(1000) 取值范围【0,1】from sklearn.ensemble import RandomFores…

单因素方差分析_基于R语言开展方差分析(一)——单因素方差分析

基本原理方差分析(Analysis of variance, ANOVA)是用于两个或两个以上样本均数比较的方法&#xff0c;还可以分析两个或多个研究因素的交互交互作用以及回归方程的线性假设检验等。其基本思想是将全部观察值间的变异——总变异按设计和需要分解成两个或多个组成部分&#xff0c…

mysql增数据语句_Mysql 数据增删改查语句

插入数据 insert#1. 插入完整数据(顺序插入)#语法一&#xff1a;insert into 表名(字段1,字段2,字段3…字段n) values (值1,值2,值3…值n);#语法二&#xff1a;insert into 表名 values (值1,值2,值3…值n);#2. 指定字段插入数据#语法&#xff1a;insert into 表名(字段1,字段2…

Python+Flask.0010.FLASK即插视图之自定义视图类及修饰器

2019独角兽企业重金招聘Python工程师标准>>> 即插视图; 说明: FLASK的视图灵感来自于DJANGO的基于类而非基于函数的通用视图,主要目的是为了解决多个视图函数之间已经实现的部分,通过类继承的方式继承到其它视图,总之为了一点,就是少写代码,然后通过add_url_rule让我…

InputStream和Reader,FileInputStream和 FileReader的区别

一、InputStream和Reader的区别 InputStream和Reader都可以用来读数据(从文件中读取数据或从Socket中读取数据)&#xff0c;最主要的区别如下: InputStream用来读取二进制数(字节流)&#xff0c;而 Reader用来读取文本数据&#xff0c;即 Unicode字符。那么二进制数与文本数据有…

NGUI之输入文本框的使用

ToolBar中的两个红圈 另&#xff0c;代码如下&#xff1a;只需要定义一个变量即可&#xff0c;然后将控件drag到那里&#xff0c;真的是灰常方便呀 还有一个就是保存了&#xff08;OK的响应&#xff09;,可以简单地理解为存档或读档 转载于:https://www.cnblogs.com/YTYMblog/p…

tensorrt轻松部署高性能dnn推理_实战教程:TensorRT中递归神经网络的介绍(中文字幕)...

NVIDIA TensorRT是一个高性能的深度学习推理优化器和运行时&#xff0c;它提供低延迟和高吞吐量。TensorRT可以从每个深度学习框架导入经过训练的模型&#xff0c;从而轻松地创建可以集成到大型应用程序和服务中的高效推理引擎。这个视频的五个关键点:1.TensorRT支持RNNv2, Mat…

w怎么接显示 树莓派zero_纯干货!一根线玩转树莓派ZeroW(图文教程,亲测有效)...

#一、写在前面本文旨在介绍如何用最少的外设(成本)完成树莓派Zero W最基础最重要的功能。注意&#xff1a;本文原始发表时官方镜像版本是2017-04-10的&#xff0c;在2019年5月10日有网友提出本方案已经不完全适用最新的镜像了&#xff0c;所以如果只是想按照本文所提出的步骤一…

十进制小数转换二进制的问题

2019独角兽企业重金招聘Python工程师标准>>> 整数和小数分别转换。 整数除以2&#xff0c;商继续除以2&#xff0c;得到0为止&#xff0c;将余数逆序排列。 22 / 2 11 余0 11/2 5 余 1 5 /2 2 余 1 2 /2 1 余 0 1 /2 0 余 1 所以22的二进制…

java操作mongodb(连接池)(转)

原文链接&#xff1a; java操作mongodb&#xff08;连接池&#xff09; Mongo的实例其实就是一个数据库连接池&#xff0c;这个连接池里默认有10个链接。我们没有必要重新实现这个链接池&#xff0c;但是我们可以更改这个连接池的配置。因为Mongo的实例就是一个连接池&#xff…

声卡突然听不到监听_音乐人/键盘手伴侣物问题之:专业监听音箱的音质必须用独立声卡...

近日&#xff0c;不少朋友在后台留言&#xff0c;询问专业监听音箱连电脑听音乐要不要接个声卡&#xff01;本期我们针对此问题&#xff0c;跟大家分享一些心得与经验。先回答问题&#xff0c;当然要&#xff01;通常我们电脑上的音频输出口是这样的&#xff1a;而专业监听音箱…

helm3安装mysql_Helm3(kubernetes包管理工具)安装使用踩坑指南

image.png从结构中我们看到有不同级别的文件夹&#xff0c;以及一些yaml文件。charts&#xff1a; 用于存放其他依赖和关联的chart。例如应用依赖数据库的chart。Chart.yaml&#xff1a;存储一些元数据&#xff0c;例如chart的信息&#xff0c;描述等等templates文件夹&#xf…

Redis-3.2主从复制与集群搭建 推荐

Redis-3.2主从复制与集群搭建 一、Redis 主从搭建 1.下载并解压 yum install -y gcc gcc-c pcre zlib pcre-devel tcl wget http://download.redis.io/releases/redis-3.2.4.tar.gz tar -zxvf redis-3.2.4.tar.gz cd redis-3.2.4 make cd src && make test &&am…

苹果手机输入屏保后锁屏_修一块手机屏幕要7080元?

这几天华为Mate X的两次开售成为大家议论的话题&#xff0c;一些抢到的人自然沉浸在快乐之中&#xff0c;想着是自己留着用&#xff0c;还是转手赚一把。而一些想抢而没抢到的人或许正在研究如何在明天的第三次开售中抓好机会吧&#xff01;当然&#xff0c;也有像小编这样的&a…

中间介(MiddleWare)

引子-Django的生命周期 在学习中间介之前&#xff0c;我们先来回顾一下Django的生命周期&#xff1a;用户发起请求&#xff0c;请求会被发送到urlconf中的url&#xff0c;然后会指向对应的views函数进行处理&#xff0c;views函数处理完成后&#xff0c;用模板渲染好html&#…

对MariaDB10.0的Sphinx进行扩展

已修改过的文件&#xff1a;http://pan.baidu.com/s/1o8DHvkA 将这两个文件放到MariaDB的解压目录后&#xff0c;再进行安装 /usr/local/mariadb-10.0.28/storage/sphinx/ 如下是修改的代码 get_rec ( byte * buf, const byte * key, uint keylen,uint a,uint b,uint c );index…

容器created状态_docker容器状态的转换实现

一 docker容器状态转换图二 实战[rootlocalhost ~]# docker infoContainers: 0Running: 0Paused: 0Stopped: 0Images: 3Server Version: 17.09.0-ceStorage Driver: overlayBacking Filesystem: xfsSupports d_type: falseLogging Driver: json-fileCgroup Driver: cgroupfsPlu…

ubuntu16.04配置sonarqube+MySQL

环境&#xff1a;rootubuntu:~# uname -a Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux rootubuntu:~# rootubuntu:~# cat /etc/issue Ubuntu 16.04 LTS \n \lrootubuntu:~#安装配置mysql&#xff1a;1、更新源…

鼠标固定在屏幕中间_无线电竞黑科技,雷柏VT950Q游戏鼠标评测

雷柏作为目前小有声誉的PC外设品牌&#xff0c;其定位高性能游戏领域的VT系列产品&#xff0c;想必大家也比较熟悉了。VT系列的产品除了有超强的性能以及出色的设计感&#xff0c;同时还都是性价比非常高的产品&#xff0c;即便是采用了旗舰级传感器&#xff0c;定位最为高端的…