SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH 实现了 发布/订阅消息范例,发送者 (publishers) 不用编程就可以向特定的接受者发送消息 (subscribers). Rather, 发布的消息进入通道,不需要知道有没有订阅者. 订阅者发表感兴趣的一个或多个通道,并且只接受他们感兴趣的消息,不管发布者是不是存在. 发布者和订阅者的解耦可以允许更大的伸缩性和更多动态的网络拓扑。

关于发布订阅(消息队列)之前也过一篇《SpringBoot进阶教程(二十二)集成RabbitMQ---MQ实战演练》。感兴趣的可以看看。今天说的发布订阅,是基于Redis的。

v准备工作

学习本章节之前,建议依次阅读以下文章,更好的串联全文内容,如已掌握以下列出知识点,请跳过:

v命令行操作发布订阅

下面实例中,图中左侧窗口视为客户端1,右侧窗口视为客户端2.

1.1 客户端1中订阅频道chatDemo

subscribe chatDemo

1.2 客户端2向频道chatDemo中发送两次消息,客户端1中会实时接收这两次消息。

publish chatDemo "Hello World."

publish chatDemo "Hello Demo."

1.3 在客户端1中退订频道,或者Ctrl+C退出redis连接模式。

unsubscribe chatDemo

以上例子中主要介绍了订阅频道、向指定的频道发布消息、然后消息推送到订阅者以及取消订阅。

v项目中操作发布订阅

2.1 消息监听类

  1. package com.demo.common;
  2.  
  3. import org.springframework.stereotype.Component;
  4.  
  5. /**
  6. * Created by toutou on 2019/2/23.
  7. */
  8. @Component
  9. public class RedisReceiver {
  10. public void receiveMessage(String message) {
  11. // TODO 这里是收到通道的消息之后执行的方法
  12. System.out.println(message);
  13. }
  14. }

2.2 Redis消息订阅配置类

  1. package com.demo.Redis;
  2.  
  3. import com.demo.common.RedisReceiver;
  4. import org.springframework.cache.annotation.EnableCaching;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.data.redis.connection.RedisConnectionFactory;
  8. import org.springframework.data.redis.core.StringRedisTemplate;
  9. import org.springframework.data.redis.listener.PatternTopic;
  10. import org.springframework.data.redis.listener.RedisMessageListenerContainer;
  11. import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
  12.  
  13. /**
  14. * Created by toutou on 2019/1/20.
  15. */
  16. @Configuration
  17. @EnableCaching
  18. public class RedisCacheConfig {
  19. @Bean
  20. RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
  21. MessageListenerAdapter listenerAdapter) {
  22.  
  23. RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  24. container.setConnectionFactory(connectionFactory);
  25. // 可以添加多个 messageListener,配置不同的交换机
  26. container.addMessageListener(listenerAdapter, new PatternTopic("channel:test"));
  27.  
  28. return container;
  29. }
  30.  
  31. /**
  32. * 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法
  33. * @param receiver
  34. * @return
  35. */
  36. @Bean
  37. MessageListenerAdapter listenerAdapter(RedisReceiver receiver) {
  38. System.out.println("消息适配器1");
  39. return new MessageListenerAdapter(receiver, "receiveMessage");
  40. }
  41.  
  42. @Bean
  43. StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
  44. return new StringRedisTemplate(connectionFactory);
  45. }
  46. }

2.3 测试接口

  1. package com.demo.controller;
  2.  
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.data.redis.core.StringRedisTemplate;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8.  
  9. import java.util.Date;
  10.  
  11. /**
  12. * Created by toutou on 2019/1/20.
  13. */
  14. @RestController
  15. @Slf4j
  16. public class RedisController {
  17. @Autowired
  18. StringRedisTemplate template;
  19.  
  20. @RequestMapping(value = "/syncmessage")
  21. public String SyncMessage(){
  22. for(int i = 1; i <= 5; i++){
  23. try{
  24. // 为了模拟消息,sleep一下。
  25. Thread.sleep(2000);
  26. }catch(InterruptedException ex){}
  27. template.convertAndSend("channel:test", String.format("我是消息{%d}号: %tT", i, new Date()));
  28. }
  29.  
  30. return "5";
  31. }
  32. }

2.4 项目目录结构

2.5 运行效果

v源码地址

https://github.com/toutouge/javademosecond/tree/master/hellospringboot

作  者:请叫我头头哥

出  处:http://www.cnblogs.com/toutou/

关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

SpringBoot进阶教程(二十九)整合Redis 发布订阅的更多相关文章

  1. SpringBoot进阶教程(二十八)整合Redis事物

    Redis默认情况下,事务支持被禁用,必须通过设置setEnableTransactionSupport(true)为使用中的每个redistplate显式启用.这样做会强制将当前重新连接绑定到触发m ...

  2. SpringBoot进阶教程(二十六)整合Redis之共享Session

    集群现在越来越常见,当我们项目搭建了集群,就会产生session共享问题.因为session是保存在服务器上面的.那么解决这一问题,大致有三个方案,1.通过nginx的负载均衡其中一种ip绑定来实现( ...

  3. SpringBoot进阶教程(二十五)整合Redis之@Cacheable、@CachePut、@CacheEvict的应用

    在上一篇文章(<SpringBoot(二十四)整合Redis>)中,已经实现了Spring Boot对Redis的整合,既然已经讲到Cache了,今天就介绍介绍缓存注解.各家互联网产品现在 ...

  4. SpringBoot进阶教程(二十四)整合Redis

    缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非 ...

  5. SpringBoot进阶教程(五十九)整合Codis

    上一篇博文<详解Codis安装与部署>中,详细介绍了codis的安装与部署,这篇文章主要介绍介绍springboot整合codis.如果之前看过<SpringBoot进阶教程(五十二 ...

  6. SpringBoot进阶教程(七十四)整合ELK

    在上一篇文章<SpringBoot进阶教程(七十三)整合elasticsearch >,已经详细介绍了关于elasticsearch的安装与使用,现在主要来看看关于ELK的定义.安装及使用 ...

  7. SpringBoot进阶教程(二十二)集成RabbitMQ---MQ实战演练

    RabbitMQ是一个在AMQP基础上完成的,可复用的企业消息系统.他遵循Mozilla Public License开源协议.RabbitMQ是流行的开源消息队列系统,用erlang语言开发.Rab ...

  8. SpringBoot进阶教程(六十九)ApplicationContextAware

    在某些特殊的情况下,Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能.为了让Bean获取它所在的 ...

  9. SpringBoot进阶教程(二十七)整合Redis之分布式锁

    在之前的一篇文章(<Java分布式锁,搞懂分布式锁实现看这篇文章就对了>),已经介绍过几种java分布式锁,今天来个Redis分布式锁的demo.redis 现在已经成为系统缓存的必备组件 ...

随机推荐

  1. 拾人牙慧篇之——linux文件挂载,基于nfs的文件共享系统安装配置

    一.写在前面 最近需要把阿里云上的四台服务器的项目迁移到客户提供的新的项目中,阿里云的项目平时开发启动的时候知道有个nfs文件系统,表现就是后台管理系统通过freemarker生成的HTML文件,自动 ...

  2. Java对象和Excel转换工具XXL-EXCEL

    <Java对象和Excel转换工具XXL-EXCEL> 一.简介 1.1 概述 XXL-EXCEL 是一个灵活的Java对象和Excel文档相互转换的工具. 一行代码完成Java对象和Ex ...

  3. 「SQL归纳」树形结构表的存储与查询功能的实现——通过路径方法(非递归)

    一.树形结构例子分析: 以360问答页面为例:http://wenda.so.com/c/ 我们通过观察URL,可以明确该页面的数据以树形结构存储,下面三块模块分别为: ①根节点 ②根节点的第一层子节 ...

  4. Sublime中文编码问题

    1. 改配置 Preferences->Settings  三个全部加上 "default_encoding": "UTF-8" 2. 代码编写 2.1 ...

  5. HTTP协议简单记录

    http协议的格式 1. 首行 2. 头 3. 空行 4. 体 http请求头 #Referer 请求来自哪里,如果是在http://www.baidu.com上点击链接发出的请求,那么Referer ...

  6. 通过数据流处理-微信小程序生成临时二维码

    1.小程序代码 onLoad: function (options) { var that = this api.Login(function (login) { var codeModel = ne ...

  7. SSM-SpringMVC-05:SpringMVC视图解析器InternalResourceViewResolver配置

     ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 视图解析器------默认就有配置,但是默认的在实际使用过程中有很多不方便的地方,所以我们配置一道视图解析器 ...

  8. String和StringBuffer的区别?

    这个我经常用的是String,说真的,用StringBuffer的次数还真是少,唯一让我觉得特别的方法就是appand这个方法是StringBuffer独有的,那么他们到底有什么区别呢,我们知道Str ...

  9. PHP 的 uniqid 函数产生的 id 真的是唯一的么?

    PHP 的 uniqid 函数产生的 id 真的是唯一的么? 最近使用到了 uniqid,就产生了疑问?uniqid 生成的 id 由什么组成?真的是唯一的么?什么情况下会产生冲突? 从文档中看到 u ...

  10. 论文阅读 | CrystalBall: A Visual Analytic System for Future Event Discovery and Analysis from Social Media Data

    CrystalBall: A Visual Analytic System for Future Event Discovery and Analysis from Social Media Data ...