一、发布和订阅机制

  当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher)。

  而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的时候,我们称这个客户端为订阅者(subscriber)。

为了解耦发布者(publisher)和订阅者(subscriber)之间的关系,Redis 使用了 channel (频道)作为两者的中介 —— 发布者将信息直接发布给 channel ,而 channel 负责将信息发送给适当的订阅者,发布者和订阅者之间没有相互关系,也不知道对方的存在

注意:Redis的Pub Sub功能(或许是暂时)不支持持久化,意思就是消息在管道中是即发即失的,Subscriber端一收到消息,消息即从管道中删除。所以如果是对消息的准确性要求比较高或者是有持久化的需求,Redis就不是那么合适了,期待以后的版本加入持久化功能。

二、Pub/Sub的作用

其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个Channel,多个Publisher可以往多个Channel中发布消息。可以这么简单的理解:

Subscriber:收音机(只不过这个收音机可以收到多个频道,并以队列方式显示)

Publisher:电台(电台可以往不同的FM频道中发消息)

Channel:不同频率的FM频道

所以根据这个理解,那么我觉得有几种用法是比较可取的:

  1.一个Publisher,多个Subscriber:

  如下图所示,可以作为消息队列或者消息管道。

  主要应用:通知、公告。

  2.多个Publisher,一个Subscriber:

  可以将PubSub做成独立的HTTP接口,各应用程序作为Publisher向Channel中发送消息,Subscriber端收到消息后执行相应的业务逻辑,比如写数据库,显示等等。

  主要应用:排行榜、投票、计数。

3.多个Publisher,多个Subscriber

图就不上了,故名思议,就是可以向不同的Channel中发送消息,由不同的Subscriber接收。

主要应用:群聊、聊天。

可参考Spring data redis主页的开源项目retwisj。

Github地址:https://github.com/spring-projects/spring-data-keyvalue-examples/tree/master/retwisj

从上述几种用法来看,根据不同的限制条件,限制Publisher、Subscriber和Channel的数量,可以实现不同的功能,其实完全可以把Pub/Sub理解为Socket编程,用Socket也可以实现上述功能,但是Redis提供了相应的封装和底层实现,不管是安全性、健壮性的等各方面都有不错的表现,以及未来的一些拓展,个人觉得Redis是个不错的选择。

三、Demo演示:

因为我的上一篇博客Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解,已经演示了Spring Data Redis的基本配置和使用,所以这里就只贴上Pub/Sub的重要代码,读者可以阅读上篇博客或者下载源码。

Pub/Sub配置(XMl):

 1 <!-- SDR Pub/Sub配置 -->2     <!-- SubServiceImpl是实现了MessageListener接口的类,MessageListener接口中定义了onMessage方法,也就是接收消息的方法,每当Channel中有消息,onMessage方法会被自动调用, -->3     <bean id="messageListener" class="com.chr.service.impl.SubServiceImpl">4     </bean>5     6     <!-- 可以有多个messageListener,每个messageListener必须注册到RedisMessageListenerContainer中,读者可参阅API文档 -->7     <bean id="messageContainer"8         class="org.springframework.data.redis.listener.RedisMessageListenerContainer"9         destroy-method="destroy">
10         <property name="connectionFactory" ref="connectionFactory" />
11         <!--<property name="taskExecutor"> <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
12 <property name="poolSize" value="3"></property> </bean> </property>
13 此处可以定义Executor,参阅java.util.concurrent.Executor-->
14         <property name="messageListeners">
15             <map>
16                 <entry key-ref="messageListener">
17                     <ref bean="channelTopic" />
18                 </entry>
19             </map>
20         </property>
21     </bean>
22
23     <!-- Channel设置 -->
24     <bean id="channelTopic" class="org.springframework.data.redis.listener.ChannelTopic">
25         <constructor-arg value="user:topic" />
26     </bean>

在代码中可以看到subServiceImpl实现类被手动注册到配置文件中,这样可能会使代码混乱,并且会带来一些问题,比如需要使用注解自动注入rankService,但是因为Spring配置中,XML的优先级大于Annotation,所以subServiceImpl中的rankService不能被@Autowired。

那么解决办法有两种:

  1.在配置文件中(messageLisener bean前)加入:

<!-- 类扫描器 --><context:component-scan base-package="com.songod.service" />

这样Spring会先扫描Annotation,创建rankService bean,之后再注入messageLisener。

  2.在messageContainer bean中,只注入connectionFactory,不注入messageLisener和channelTopic。 之后在Controller中手动注入,调用addMessageListener(MessageListener listener, Topic topic)方法手动注入,但是注意只能注入一次,可以设置Flag判断。

PubServiceImpl:

 1 @Service2 public class PubServiceImpl implements PubService {3     @Resource(name="stringRedisTemplate")4     private  StringRedisTemplate stringRedisTemplate;5     6     private String channelTopic = "user:topic";7     8     /*发布消息到Channel*/9     public void Publisher(String message) {
10         stringRedisTemplate.convertAndSend(channelTopic, message);
11     }
12 }

我这里用的是StringRedisTemplate,读者可以使用RedisTemplate设置其它序列化方式,可以看我的上一篇博客。

SubServiceImpl:

public class SubServiceImpl implements SubService {@Autowiredprivate ChannelTopic channelTopic;private MessageList messageList = new MessageList();public void onMessage(Message message, byte[] pattern) {System.out.println(message.toString() + "  " + channelTopic.getTopic());messageList.add(message.toString());}public MessageList getMessageList() {return messageList;}
}

主要是onMessage方法,可以在此方法中将message传入其它业务逻辑中进行处理。

四、Demo运行:

Publish:

Subscrib:

五、项目源码:

redis-web-pubsub

Spring mvc Data Redis—Pub/Sub(附Web项目源码)相关推荐

  1. 简单开源java ssm_[VIP源码]【S006】SSM(Spring+Spring MVC+Mybatis) java开源博客管理系统项目源码...

    java源码项目名称:SSM(Spring+Spring MVC+Mybatis) java开源博客管理系统项目源码  java项目源码 1 ?, R, _* q  n8 v) S$ R7 ?百度网盘 ...

  2. Spring Data Redis—Pub/Sub(附Web项目源码)

    一.发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE ...

  3. SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载

    转载自   SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载 基本准备工作 1.安装JDK1.6以上版本,安装与配置 2.下载mybatis-3.2.0版:htt ...

  4. c# 读cpu温度,显卡温度,硬盘温度,风扇转速,硬件信息,cpu占用,附赠项目源码

    http://download.csdn.net/download/fireghost57/9969844 OpenHardwareMonitor源码工程 读cpu温度,显卡温度,硬盘温度,风扇转速, ...

  5. 影院在线售票云平台(仿猫眼电影,附SpringBoot项目源码) 系统功能实现

    影院在线售票云平台是模仿猫眼电影开发的在线售票系统,系统分为前端网站及后台管理2部分,主要功能有影院管理,电影管理,影厅管理,排片管理,选座售票,演员管理,评论管理,影片排名,票房收入,票房排名,财务 ...

  6. 视频教程-影院在线售票云平台(仿猫眼电影,附SpringBoot项目源码)-Java

    影院在线售票云平台(仿猫眼电影,附SpringBoot项目源码) 19年软件开发经验,设计开发40多个大型软件,10年从事高等教育,主要为java系列课程,带你轻松进入java生涯. 赖国荣 ¥299 ...

  7. 使用Spring MVC,Mybatis框架等创建Java Web项目时各种前期准备的配置文件内容

    1.pom.xml 首先,pom.xml文件,里面包含各种maven的依赖,代码如下: <project xmlns="http://maven.apache.org/POM/4.0. ...

  8. 【持久化框架】SpringMVC+Spring4+Mybatis3 集成,开发简单Web项目+源码下载

    通过spring与Mybatis集成,开发一个简单用户增删改查的Web项目. 基本准备工作 1.安装JDK1.6以上版本,安装与配置 2.下载mybatis-3.2.0版:https://repo1. ...

  9. 【持久化框架】SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载【转】

    为什么80%的码农都做不了架构师?>>>    第一步:创建数据库表 在Navicat下执行如下sql命令创建数据库mybatis和表t_user CREATE DATABASE I ...

最新文章

  1. 【网站汇总】论文相关
  2. KafkaOffsetMonitor 安装
  3. oracle ohs是什么,怎么更改OHS端口为80
  4. 中国最懂自动驾驶量产公司秀肌肉:自动驾驶算力怪兽、百亿参数云端超大模型、百万公里路测里程...
  5. adas技术实现途径_未来实现100%清洁电力的途径,带来巨大的健康和工作
  6. FXRibbon 1.2版发布
  7. idea使用junit测试_在JUnit测试中使用Builder模式
  8. shell总结(0基础入门)
  9. mybatis日志能正常打印出正确sql执行语句;数据库有内容;却查询不出来
  10. linux shell 多线程执行程序
  11. oracle10自动扩分区,Oracle 11g数据库的分区表扩展(按年度)
  12. [转载]年末致富有新招,写个程序抓红包
  13. 【Linux-Windows】海康网络相机开启ONVIF协议
  14. 多应用集中落地,四川区块链产业爆发增长
  15. Couldn't Copy Base System 错误处理办法
  16. 《光剑文集》青玉案: 27首
  17. Unity 生命周期
  18. 股票交易接口申请方式有哪几种?
  19. 大象装进冰箱要几步?Python 来解答
  20. Linux Kernel suspend/resume 过程

热门文章

  1. 转帖 javascript事件监听
  2. WinForm 读写配置文件
  3. [导入]郁闷`````[原]
  4. iOS--MD5加密封装
  5. SpringBoot-JPA入门
  6. c++面试题中经常被面试官面试的小问题总结(一)(本篇偏向基础知识)
  7. 贾扬清:我对人工智能方向的一点浅见
  8. LaTeX - 带圈数字
  9. Centos+PHP模块+exif扩展 (第三方模块)
  10. C#设计模式(7)——适配器模式(Adapter Pattern)