展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > SpringBoot整合RabbitMq的方法是什么

SpringBoot整合RabbitMq的方法是什么

SpringBoot整合RabbitMq实战spring-boot-starter-amqp高级消息队列协议(AMQP)是面向消息中间件的平台中立的有线协议。SpringAMQP项目将核心Spring概念应用于基于AMQP的消息传递解决方案的开发。SpringBoot为通过RabbitMQ与AMQP一起工作提供了一些便利,包括spring-boot-starter-amqp“Starter”。springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spri

本文目录

    SpringBoot 整合RabbitMq 实战

    spring-boot-starter-amqp

    高级消息队列协议(AMQP)是面向消息中间件的平台中立的有线协议。Spring AMQP项目将核心Spring概念应用于基于AMQP的消息传递解决方案的开发。Spring Boot为通过RabbitMQ与AMQP一起工作提供了一些便利,包括spring-boot-starter-amqp “Starter”。

    springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持。

    添加依赖

    
                org.springframework.boot
                spring-boot-starter-amqp
            

    RabbitMQ是基于AMQP协议的轻量级,可靠,可扩展,可移植的消息代理。Spring使用RabbitMQ通过AMQP协议进行通信。

    属性配置

    RabbitMQ配置由外部配置属性控制 spring.rabbitmq.*。例如,您可以在以下部分声明以下部分 application.properties:

    spring.rabbitmq.host = localhost
     spring.rabbitmq.port = 5672
     spring.rabbitmq.username = guest
     spring.rabbitmq.password

    快速上手

    1.队列配置

    package com.example.rabbitmqdemo.config;
    
    
    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * RabbitMQ 配置类
     *
     * @author itguang
     * @create
    @Configuration
    public class RabbitConfig
    
        @Bean
        public Queue queue(){
            return new Queue("hello");
        }
    }

    2 发送者

    rabbitTemplate是springboot 提供的默认实现.

    package com.example.rabbitmqdemo.rabbitmq;
    
    import org.springframework.amqp.core.AmqpTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    import java.util.Date;
    
    /**
     * 消息发送者
     *
     * @author itguang
     * @create
    
    @Component
    public class HelloSender
    
    
        @Autowired
        private AmqpTemplate amqpTemplate;
    
    
        public void send(){
            String context = "hello----"+LocalDateTime.now();
            System.out.println("send:"+context);
            //往名称为 hello 的queue中发送消息
            this.amqpTemplate.convertAndSend("hello",context);
        }
    
    }

    3 接收者

    package com.example.rabbitmqdemo.rabbitmq;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    /**
     * 消息接受者
     *
     * @author itguang
     * @create
    
    @Component
    @RabbitListener(queues = "hello") //监听 名称为 hello 的queue
    public class HelloReceiver
    
        //消息处理器
        @RabbitHandler
        public void process(String message){
            System.out.println("Receiver:"+message);
    
        }
    
    
    }

    测试

    package com.example.rabbitmqdemo;
    
    import com.example.rabbitmqdemo.rabbitmq.HelloSender;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class RabbitmqdemoApplicationTests
    
        @Autowired
        HelloSender helloSender;
    
        @Test
        public void contextLoads() {
            helloSender.send();
    
        }
    }

    查看控制台输出结果

    send:hello----2018-04-21T11:29:47.739
    Receiver:hello----2018-04-21T11:29:47.739

    一对多发送:一个发送者多个接受者

    对上面的代码进行了小改造,接收端注册了两个Receiver,Receiver1和Receiver2,发送端加入参数计数,接收端打印接收到的参数,下面是测试代码,发送一百条消息,来观察两个接收端的执行效果

    • 添加一个队列叫 hello2

    package com.example.rabbitmqdemo.config;
    
    
    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * RabbitMQ 配置类
     *
     * @author itguang
     * @create
    @Configuration
    public class RabbitConfig
    
    
    
        @Bean
        public Queue queue(){
            return new Queue("hello");
        }
    
        @Bean
        public Queue queue2(){
            return new Queue("hello2");
        }
    
    
    
    }
    • 给队列 hello2 发送消息,接受一个计数参数

    package com.example.rabbitmqdemo.rabbitmq;
    
    import org.springframework.amqp.core.AmqpTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    import java.util.Date;
    
    /**
     * 消息发送者
     *
     * @author itguang
     * @create
    
    @Component
    public class HelloSender
    
    
        @Autowired
        private AmqpTemplate amqpTemplate;
    
    
        public void send(){
            String context = "hello----"+LocalDateTime.now();
            System.out.println("send:"+context);
            this.amqpTemplate.convertAndSend("hello",context);
        }
    
        //给hello2发送消息,并接受一个计数参数
        public void send2(int i){
            String context = i+"";
            System.out.println(context+"--send:");
            this.amqpTemplate.convertAndSend("hello2",context);
        }
    }
    • 两个hello2 的接受者

    @Component
    @RabbitListener(queues = "hello2")
    public class HelloReceiver1
    
    
        @RabbitHandler
        public void process(String message){
    
            System.out.println("Receiver1:"+message);
        }
    
    
    }
    @Component
    @RabbitListener(queues = "hello2")
    public class HelloReceiver2
    
        @RabbitHandler
        public void process(String message){
            System.out.println("Receiver2:"+message);
        }
    }

    测试

    @Test
        public void manyReceiver(){
            for (int i=0;i<100;i++){
                helloSender.send2(i);
            }
    
        }

    查看控制台输出结果:

    0--send:
    1--send:
    2--send:
    3--send:
    4--send:
    
    ...(省略)
    
    58--send:
    59--send:
    60--send:
    61--send:
    62--send:
    63--send:
    Receiver2:1
    Receiver1:0
    64--send:
    65--send:
    Receiver1:2
    Receiver2:3
    66--send:
    Receiver1:4
    Receiver2:5
    ...(省略)

    可以看到:在消息发送到63时,接受者Receiver已经收到了消息,
    结论:

    一个发送者,N个接受者,经过测试会均匀的将消息发送到N个接收者中

    多对多: 多个发送者对多个接受者

    我们可以注入两个发送者,放在循环中,如下:

    @Test
        public void many2many(){
          for (int i=0;i<100;i++){
              helloSender.send2(i);
              helloSender2.send2(i);
    
          }
        }

    运行单元测试,查看控制台输出:

    0--send:
    0--send:
    1--send:
    1--send:
    2--send:
    2--send:
    3--send:
    3--send:
    
    ...(省略)
    
    22--send:
    22--send:
    23--send:
    23--send:
    24--send:
    24--send:
    Receiver2:0
    25--send:
    25--send:
    Receiver2:1
    26--send:
    Receiver2:2
    26--send:
    Receiver2:3
    27--send:
    Receiver1:0
    27--send:
    Receiver2:4
    Receiver1:1
    28--send:
    Receiver2:5
    Receiver1:2
    28--send:
    Receiver2:6
    Receiver1:3
    29--send:
    Receiver2:7
    Receiver1:4
    29--send:
    Receiver2:8
    Receiver1:5
    30--send:
    Receiver2:9
    Receiver1:6
    30--send:
    31--send:
    31--send:
    32--send:
    32--send:

    结论:和一对多一样,接收端仍然会均匀接收到消息

    发送对象

    首先我们创建一个实体类对象 User,注意必须实现 Serializable 接口.

    package com.example.rabbitmqdemo.pojo;
    
    import java.io.Serializable;
    
    /**
     * @author itguang
     * @create
    public class User implements Serializable
    
    
        private String username;
        private String password;
    
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }

    然后在配置文件中再创建一个队列,叫 object_queue

    @Bean
        public Queue queue3(){
            return new Queue("object_queue");
        }

    接下里就是User对象的两个发送者ObjectSender和接受者ObjectReceiver:

    @Component
    public class ObjectSender
    
        @Autowired
        AmqpTemplate amqpTemplate;
    
        public void sendUser(User user){
    
            System.out.println("Send object:"+user.toString());
            this.amqpTemplate.convertAndSend("object_queue",user);
    
        }
    }
    @Component
    @RabbitListener(queues = "object_queue")
    public class ObjectReceiver
    
        @RabbitHandler
        public void objectReceiver(User user){
    
            System.out.println("Receiver object:"+user.toString());
    
        }
    }

    运行单元测试,查看控制台输出结果:

    Send object:User{username='李增光', password='666666'}
    Receiver object:User{username='李增光', password='666666'}

    Topic Exchange

    topic 是RabbitMQ中最灵活的一种方式,可以根据routing_key自由的绑定不同的队列

    首先对topic规则配置,这里使用两个队列来测试

    package com.example.rabbitmqdemo.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.core.TopicExchange;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author itguang
     * @create
    @Configuration
    public class TopicRabbitConfig
    
    
        final static String message = "topic.message";
        final static String messages = "topic.messages";
    
    
        //创建两个 Queue
        @Bean
        public Queue queueMessage(){
            return new Queue(TopicRabbitConfig.message);
        }
    
        @Bean
        public Queue queueMessages(){
            return new Queue(TopicRabbitConfig.messages);
        }
    
        //配置 TopicExchange,指定名称为 topicExchange
        @Bean
        public TopicExchange exchange(){
            return new TopicExchange("topicExchange");
        }
    
        //给队列绑定 exchange 和 routing_key
    
        @Bean
        public Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange){
            return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
        }
    
        @Bean
        public Binding bingingExchangeMessages(Queue queueMessages,TopicExchange exchange){
            return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
        }
    
    
    }

    消息发送者:都是用topicExchange,并且绑定到不同的 routing_key

    package com.example.rabbitmqdemo.topic;
    
    import org.springframework.amqp.core.AmqpTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    /**
     * @author itguang
     * @create
    @Component
    public class TopicSender
    
        @Autowired
        AmqpTemplate amqpTemplate;
    
        public void send1(){
            String context = "hi, i am message 1";
            System.out.println("Sender : " + context);
            amqpTemplate.convertAndSend("topicExchange","topic.message",context);
        }
    
        public void send2() {
            String context = "hi, i am messages 2";
            System.out.println("Sender : " + context);
            amqpTemplate.convertAndSend("topicExchange", "topic.messages", context);
        }
    }

    两个消息接受者,分别指定不同的 queue

    package com.example.rabbitmqdemo.topic;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    /**
     * @author itguang
     * @create
    @Component
    @RabbitListener(queues = "topic.message")
    public class TopicReceiver1
    
        @RabbitHandler
        public void process(String message){
    
            System.out.println("Receiver topic.message :"+ message);
    
        }
    
    }
    package com.example.rabbitmqdemo.topic;
    
    import org.springframework.amqp.rabbit.annotation.RabbitHandler;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.stereotype.Component;
    
    /**
     * @author itguang
     * @create
    @Component
    @RabbitListener(queues = "topic.messages")
    public class TopicReceiver2
    
        @RabbitHandler
        public void process(String message){
    
            System.out.println("Receiver topic.messages: "+ message);
    
        }
    
    }

    测试:

    发送send1会匹配到topic.#和topic.message 两个Receiver都可以收到消息,发送send2只有topic.#可以匹配所有只有Receiver2监听到消息

    Fanout Exchange

    Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。

    Fanout 相关配置:

    package com.example.rabbitmqdemo.config;
    
    import org.springframework.amqp.core.Binding;
    import org.springframework.amqp.core.BindingBuilder;
    import org.springframework.amqp.core.FanoutExchange;
    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.security.PublicKey;
    
    /**
     * @author itguang
     * @create
    @Configuration
    public class FanOutRabbitMq
    
    
        //创建三个队列
    
        @Bean
        public Queue AMessage() {
            return new Queue("fanout.A");
        }
    
        @Bean
        public Queue BMessage() {
            return new Queue("fanout.B");
        }
    
        @Bean
        public Queue CMessage() {
            return new Queue("fanout.C");
        }
    
    
        //创建exchange,指定交换策略
    
        @Bean
        public FanoutExchange fanoutExchange() {
    
            return new FanoutExchange("fanoutExchange");
        }
    
    
        //分别给三个队列指定exchange,这里使用了A、B、C三个队列绑定到Fanout交换机上面,发送端的routing_key写任何字符都会被忽略:
    
        @Bean
        public Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange){
            return BindingBuilder.bind(AMessage).to(fanoutExchange);
    
        }
    
        @Bean
        public Binding bindingExchangeB(Queue BMessage,FanoutExchange fanoutExchange){
            return BindingBuilder.bind(BMessage).to(fanoutExchange);
    
        }
    
        @Bean
        Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
            return

    消息发送者:

    这里使用了A、B、C三个队列绑定到Fanout交换机上面,发送端的routing_key写任何字符都会被忽略

    package com.example.rabbitmqdemo.fanout;
    
    import org.springframework.amqp.core.AmqpTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    /**
     * @author itguang
     * @create
    @Component
    public class FanoutSender
    
    
        @Autowired
        AmqpTemplate amqpTemplate;
    
    
        public void send(){
    
            String context = "hi, fanout msg ";
            System.out.println("Sender : " + context);
            //这里使用了A、B、C三个队列绑定到Fanout交换机上面,发送端的routing_key写任何字符都会被忽略:
            amqpTemplate.convertAndSend("fanoutExchange","", context);
    
        }
    
    }

    三个消息接受者:

    @Component
    @RabbitListener(queues = "fanout.A")
    public class FanoutReceiverA
    
    
        @RabbitHandler
        public void process(String message){
    
            System.out.println("Receiver form fanout.A: "+message);
    
        }
    
    }
    
    @Component
    @RabbitListener(queues = "fanout.B")
    public class FanoutReceiverB
    
    
        @RabbitHandler
        public void process(String message){
    
            System.out.println("Receiver form fanout.B: "+message);
    
        }
    
    }
    
    @Component
    @RabbitListener(queues = "fanout.C")
    public class FanoutReceiverC
    
    
        @RabbitHandler
        public void process(String message){
    
            System.out.println("Receiver form fanout.C: "+message);
    
        }
    
    }

    运行单元测试,查看结果:

    Sender : hi, fanout msg 
    
    Receiver form fanout.C: hi, fanout msg 
    Receiver form fanout.A: hi, fanout msg 
    Receiver form fanout.B: hi, fanout msg

    结果说明,绑定到fanout交换机上面的队列都收到了消息.

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。