SpringBoot+Redis实现消息的发布与订阅的示例代码

 更新时间:2022年04月08日 16:10:17   作者:逆着黑夜便是光  
本文主要介绍了SpringBoot+Redis实现消息的发布与订阅,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.什么是redis的发布与订阅

在官网的文档介绍中有一行介绍:Redis是一个快速稳定的发布/订阅消息系统。

2.Redis发布订阅

机制

Redis提供了发布与订阅的功能,可以用于消息的传输,Redis的发布订阅机制包括三部分,发布者、订阅者和Channel(主题或者队列)。

3.命令行实现功能

订阅主题

Redis采用SUBSCRIBE channel命令订阅某个主题,返回的参数subscribe表示已经成功订阅主题,第二个参数表示订阅的主题名称,第三个表示当前订阅数

127.0.0.1:6379> SUBSCRIBE ORDER-PAY-SUCCESS
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "ORDER-PAY-SUCCESS"
3) (integer) 1

模式匹配订阅

模式匹配功能是允许客户端订阅匹配某种模式的频道,Redis采用PSUBSCRIBE channel命令订阅匹配某种模式的所有频道,用*表示模式,*可以被任意值代替。

127.0.0.1:6379> PSUBSCRIBE ORDER-PAY-*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "ORDER-PAY-*"
3) (integer) 1

发布消息

Redis采用PUBLISH channel message命令在某个主题上发布消息,返回的参数是接收到消息的订阅者个数

127.0.0.1:6379> PUBLISH ORDER-PAY-SUCCESS DD202109071525
(integer) 1

取消订阅

Redis采用UNSUBSCRIBE channel或PUNSUBSCRIBE channel命令取消某个主题的订阅,由于Redis的订阅操作是阻塞式的,因此一旦客户端订阅了某个频道或模式,就将会一直处于订阅状态直到退出。在 SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE 和 PUNSUBSCRIBE 命令中,其返回值都包含了该客户端当前订阅的频道和模式的数量,当这个数量变为0时,该客户端会自动退出订阅状态。

127.0.0.1:6379> UNSUBSCRIBE ORDER-PAY-SUCCESS
1) "unsubscribe"
2) "ORDER-PAY-SUCCESS"
3) (integer) 0
127.0.0.1:6379> PUNSUBSCRIBE ORDER-PAY-SUCCESS
1) "punsubscribe"
2) "ORDER-PAY-SUCCESS"
3) (integer) 0

测试

首先三个订阅者订阅ORDER-PAY-SUCCESS主题,当发送者在这个主题内发送订单号时,所有的订阅者都会收到这个主题的消息。

4.SpringBoot实现功能

Springboot整合Redis

引入依赖包

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.4.1</version>
        </dependency>
    </dependencies>

配置yaml文件

server:
  port: 8888

spring:
  application:
    name: spring-boot-redis
  redis:
    host: 127.0.0.1
    port: 6379

配置消息监听

import com.demo.redis.listener.MessageListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

/**
 * @author Bai
 * @date 2021/4/29 上午 11:17
 * @description
 */
@Configuration
public class RedisMessageConfig {

    /**
     * 监听订单支付完成主题
     */
    private static final String ORDER_PAY_SUCCESS = "ORDER-PAY-SUCCESS";

    /**
     * 注入消息监听适配器
     * @param messageListener
     * @return {@link MessageListenerAdapter}
     * @throws
     * @author Bai
     * @date 2021/9/7 下午 03:54
     */
    @Bean
    public MessageListenerAdapter getMessageListenerAdapter(MessageListener messageListener){
        return new MessageListenerAdapter(messageListener, "onMessage");
    }

    /**
     * 注入消息监听容器
     * @param redisConnectionFactory
     * @param messageListenerAdapter
     * @return {@link RedisMessageListenerContainer}
     * @throws
     * @author Bai
     * @date 2021/9/7 下午 03:54
     */
    @Bean
    public RedisMessageListenerContainer getRedisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListenerAdapter){
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);

        //订阅订单支付成功主题
        redisMessageListenerContainer.addMessageListener(messageListenerAdapter, new PatternTopic(ORDER_PAY_SUCCESS));
        return redisMessageListenerContainer;
    }

    /**
     * 处理内容
     * @param connectionFactory
     * @return {@link StringRedisTemplate}
     * @throws
     * @author Bai
     * @date 2021/9/7 下午 04:01
     */
    @Bean
    StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }
}

接收消息

import org.springframework.stereotype.Component;

/**
 * @author Bai
 * @date 2021/9/7 下午 03:51
 * @description
 */
@Component
public class MessageListener {

    public void onMessage(String message){
        System.out.println("接收消息:" + message);
    }
}

测试

发送订单支付成功的消息

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @author Bai
 * @date 2021/9/7 下午 04:32
 * @description
 */
@RunWith(value = SpringRunner.class)
@SpringBootTest
public class RedisPubTest {

    /**
     * 订单支付完成主题
     */
    private static final String ORDER_PAY_SUCCESS = "ORDER-PAY-SUCCESS";

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 模拟发送5调订单支付完成的消息
     * @throws
     * @author Bai
     * @date 2021/9/7 下午 04:57
     */
    @Test
    public void sendMessage(){
        for (int i = 0; i < 5; i++) {
            stringRedisTemplate.convertAndSend(ORDER_PAY_SUCCESS,"DD" + System.currentTimeMillis());
        }
    }
}

接收到订单支付成功的消息

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v2.2.10.RELEASE)

2021-09-07 16:56:54.729  INFO 3712 --- [           main] com.demo.redis.RedisSubPubApplication    : Starting RedisSubPubApplication on DESKTOP-595LI4G with PID 3712 (D:\Bai\Sources\spring-boot-demo\redis-sub-pub\target\classes started by 1 in D:\Bai\Sources\spring-boot-demo)
2021-09-07 16:56:54.735  INFO 3712 --- [           main] com.demo.redis.RedisSubPubApplication    : No active profile set, falling back to default profiles: default
2021-09-07 16:56:55.205  INFO 3712 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-09-07 16:56:55.207  INFO 3712 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2021-09-07 16:56:55.229  INFO 3712 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 11 ms. Found 0 Redis repository interfaces.
2021-09-07 16:56:55.557  INFO 3712 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8888 (http)
2021-09-07 16:56:55.565  INFO 3712 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-09-07 16:56:55.565  INFO 3712 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.38]
2021-09-07 16:56:55.669  INFO 3712 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-09-07 16:56:55.669  INFO 3712 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 895 ms
2021-09-07 16:56:56.032  INFO 3712 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-09-07 16:56:56.950  INFO 3712 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8888 (http) with context path ''
2021-09-07 16:56:56.952  INFO 3712 --- [           main] com.demo.redis.RedisSubPubApplication    : Started RedisSubPubApplication in 2.557 seconds (JVM running for 3.436)
接收消息:DD1631005025949
接收消息:DD1631005025964
接收消息:DD1631005025965
接收消息:DD1631005025967
接收消息:DD1631005025968

到此这篇关于SpringBoot+Redis实现消息的发布与订阅的示例代码的文章就介绍到这了,更多相关SpringBoot Redis消息发布与订阅内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中关于命令执行汇总

    java中关于命令执行汇总

    这篇文章主要介绍了java中关于命令执行汇总,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java SPEL表达式注入漏洞原理解析

    Java SPEL表达式注入漏洞原理解析

    SpEL简称Spring表达式语言,在Spring 3中引入,SpEL能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,可以与基于XML和基于注解的Spring配置还有bean定义一起使用,本文给大家介绍Java SPEL表达式注入漏洞原理研究,感兴趣的朋友一起看看吧
    2023-10-10
  • struts升级到2.5.2遇到的问题及解决方案(推荐)

    struts升级到2.5.2遇到的问题及解决方案(推荐)

    原来的版本是2.3.x,由于安全原因需要升级到2.5.2。但是在升级过程中遇到各种各样的问题,下面小编给大家带来了struts升级到2.5.2遇到的问题及解决方案,需要的朋友参考下吧
    2016-11-11
  • Java编程一个随机数产生模块代码分享

    Java编程一个随机数产生模块代码分享

    这篇文章主要介绍了Java编程一个随机数产生模块代码分享,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Spring中事务管理的四种方法(银行转账为例)

    Spring中事务管理的四种方法(银行转账为例)

    这篇文章主要给大家介绍了关于Spring中事务管理的四种方法,文中是以银行转账为例,通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • 超实用的Java快捷键(总结)

    超实用的Java快捷键(总结)

    下面小编就为大家带来一篇超实用的Java快捷键(总结)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 深入理解Java中的克隆

    深入理解Java中的克隆

    想必大家对克隆都有耳闻,世界上第一只克隆羊多莉就是利用细胞核移植技术将哺乳动物的成年体细胞培育出新个体,甚为神奇。其实在Java中也存在克隆的概念,即实现对象的复制。本文将尝试介绍一些关于Java中的克隆和一些深入的问题,希望可以帮助大家更好地了解克隆。
    2016-08-08
  • JAVA判断两个时间之间的差

    JAVA判断两个时间之间的差

    经常会遇到需要判断两个时间之间的差异的情况,本文主要介绍了JAVA计算两个时间之间的差,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Spring Cloud 专题之Sleuth 服务跟踪实现方法

    Spring Cloud 专题之Sleuth 服务跟踪实现方法

    这篇文章主要介绍了Spring Cloud 专题之Sleuth 服务跟踪,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • Java如何根据key值修改Hashmap中的value值

    Java如何根据key值修改Hashmap中的value值

    这篇文章主要介绍了Java如何根据key值修改Hashmap中的value值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论