订阅发布功能Java实现
前言
订阅发布最常见的就是在公众号的订阅,用户订阅了公众号后,公众号发布消息时就能收到。其实他相当于设计模式中的观察者模式
大致流程图
用户首先对感兴趣的服务进行订阅,该服务在发送消息时会将消息发送至所有订阅的用户。
实现
接口定义
使用java实现的版本
首先定义下接口,再对其进行实现。
public interface Service {boolean addSubscribe(Observice observice); // 增加订阅者boolean removeSubscribe(Observice observice); // 删除订阅者void push(Object o); // 推送消息
}
这是一个服务的接口,声明了3个主要的方法,分别是增加订阅,删除订阅,以及推送消息。
public interface Observice {void gotIt(Object s); // 收到消息后的动作String getId();String getName();
}
这个接口用来作为用户的接口,提供获取Id,name以及消息订阅后的动作。
接口实现
下面是消息服务的实现,在收到订阅后根据id放到map里,然后根据id删除。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class MessageService implements Service {private static Map<String,Observice> observerMap = new ConcurrentHashMap<>();@Overridepublic boolean addSubscribe(final Observice observice) {observerMap.put(observice.getId(),observice);System.out.println(String.format("用户Id %s 姓名 %s 插入成功 ", observice.getId(), observice.getName()));return true;}@Overridepublic boolean removeSubscribe(final Observice observice) {if (observerMap.get(observice.getId()) == null){System.out.println(String.format("用户Id %s 姓名 %s 不存在 移除失败", observice.getId(), observice.getName()));return false;}observerMap.remove(observice.getId());System.out.println(String.format("用户Id %s 姓名 %s 已经移除 ", observice.getId(), observice.getName()));return true;}@Overridepublic synchronized void push(Object S) {if (null == S) return;observerMap.forEach((k,v)-> v.gotIt(S));// 推送时采用轮训推送System.out.println("所有消息推送完毕");}
下面是用户接口的实现,在收到消息后只是简单的打印了出来
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class VipUser implements Observice {private String id;private String username;@Overridepublic void gotIt(Object s) {System.out.print("收到了推送:\t");System.out.println(s);}@Overridepublic String getId() {return this.id;}@Overridepublic String getName() {return this.username;}}
测试
在编写完后对整个流程进行测试
public static void main(String[] args) {Service service = new MessageService();Observice user1 = new VipUser("1","小李");Observice user2 = new VipUser("2","小王");Observice user3 = new VipUser("3","小张");// 每个用户都进行订阅service.addSubscribe(user1);service.addSubscribe(user2);service.addSubscribe(user3);service.push("大家好,这是第一条推送");// 推送消息service.removeSubscribe(user2);service.removeSubscribe(user2);// 移除两次,会提示移除失败。service.push("大家好,这条推送没小王");}
结果如下
用户Id 1 姓名 小李 插入成功
用户Id 2 姓名 小王 插入成功
用户Id 3 姓名 小张 插入成功
收到了推送: 大家好,这是第一条推送
收到了推送: 大家好,这是第一条推送
收到了推送: 大家好,这是第一条推送
所有消息推送完毕
用户Id 2 姓名 小王 已经移除
用户Id 2 姓名 小王 不存在 移除失败
收到了推送: 大家好,这条推送没小王
收到了推送: 大家好,这条推送没小王
所有消息推送完毕
小结
通过这个小栗子可以初步的了解这种模式的设计,这样可以使用户和服务进行松耦合,用户可以随意的选择服务进行订阅,消息也可以精准的推送。
以下是代码存放的地址,没几个文件,萌新们可以一起来学习下。 [项目Demo地址](https://github.com/zza1998/java-mac/tree/master/src/main/java/com/zza/subscribe)
订阅发布功能Java实现相关推荐
- Java实现Redis的订阅发布功能,亲测可以
文章目录 简介 Redis发布订阅 Java发布订阅 简介 首先我们得知道,当一个用户订阅了某个频道,那么他就会一直在那监听该频道是否发出消息,是一种阻塞的状态,所以,我们把订阅功能用多线程来实现,给 ...
- python 实现redis订阅发布功能
redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...
- python redis 订阅发布_python 实现redis订阅发布功能
redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...
- Redis的订阅发布功能对比RabbitMQ消息队列
1.对比 特性 redis RabbitMQ 可靠性 没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中 具有消息消费确认机制,如果发布一 ...
- PHP 简易聊天室 利用redis的订阅发布功能
demo: http://www.200ok.fun:8083/api/chat/list 前言: 这个种方式太耗redis连接数,每次订阅都会新起一个进程,仅供练手使用,切勿用于生产环境. 原理: ...
- MSSQLSERVER订阅发布闭坑指南
SqlServer的订阅发布功能可以准实时的备份数据库,用来做读写分离都是可以的,简单好用 以下是亲身经历闭坑指南 准备工作 1,确定安装了数据库的复制功能,如果没有重新运行数据库安装包就可以增加这个 ...
- [Java]SpringBoot2整合mqtt服务器EMQ实现消息订阅发布入库(二)
又到了显摆分享技术的时候了 没有看过上一篇文章的可以先看一下,这篇是在上一篇基础上接着添加功能 SpringBoot2整合mqtt服务器EMQ实现消息订阅发布入库(一) 这篇文章的流程为: 1.Spr ...
- java发布后功能不能用,急项目发布后java写的打印功能失效了-求解解决方法
当前位置:我的异常网» J2EE » 急项目发布后java写的打印功能失效了-求解解决方法 急项目发布后java写的打印功能失效了-求解解决方法 www.myexceptions.net 网友分享于 ...
- Java设计模式-观察者模式(订阅发布模式)
Java设计模式-观察者模式(订阅发布模式) 一起来看 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一起坚持吧!! ...
最新文章
- ASP.NET MVC Framework 系列
- C++实现平衡二叉树
- python爬虫背景_利用Python代码实现一键抠背景功能
- Python 中 pass的使用
- Openfire配置过程,以及与php交互注意事项。
- 【AAAI 2018】腾讯 AI Lab 11篇论文精选:图像描述、NMT 模型、图卷积神经网络、DNN优化等
- C#中的修饰符及其说明
- 云小课 | 守护网络安全不是问题,iptables的四表五链为你开启“八卦阵”
- ubuntu16.04 安装apache2报错 解决方案
- Nginx 日志配置实践
- 前后端分离项目,标准json协议格式参考
- Mysql 按 create_time 排序导致的问题
- 恒强制版系统980_恒功率、大功率及无线充电,充电设备面临哪些趋势和挑战?...
- android 歌词 开源,NLyric 网易云音乐歌词自动搜索下载【开源】
- 计算机图片文档怎么着,【电脑知识】怎样将图片转换成word文档
- python 节气_Python开源日志01:pyGregorian2LunarCalendar公历农历转换、阳历阴历转换、二十四节气计算...
- 线性代数【18】点积和对偶性
- 机器人大冒险(能否到达终点)
- 阿尔弗雷德.爱因斯坦论莫扎特钢协
- 为什么说继承是把双刃剑
热门文章
- 服务器装什么操作系统好?
- uniapp使用Dplayer.js实现视频播放
- 什么是信噪比?信噪比越大好还是越小好?
- python 将函数封装成pyd或者so文件,调用该文件
- 阿里云服务器 之 mqtt服务器搭建及使用
- 外包?第一份软件测试工作就一路高歌猛进,读书学Z渣一个现在生龙活虎
- 【redis】SpringBoot整合+geo地理位置应用
- 医学统计学 第七章(假设检验)
- redhat linux光盘4,技巧:把3张Redhat Linux 9的安装光盘刻录到一张DVD光盘中
- js:如何监听history的pushState方法和replaceState方法。(高阶函数封装+自定义事件)