前言

订阅发布最常见的就是在公众号的订阅,用户订阅了公众号后,公众号发布消息时就能收到。其实他相当于设计模式中的观察者模式

大致流程图

用户首先对感兴趣的服务进行订阅,该服务在发送消息时会将消息发送至所有订阅的用户。

实现

接口定义

使用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实现相关推荐

  1. Java实现Redis的订阅发布功能,亲测可以

    文章目录 简介 Redis发布订阅 Java发布订阅 简介 首先我们得知道,当一个用户订阅了某个频道,那么他就会一直在那监听该频道是否发出消息,是一种阻塞的状态,所以,我们把订阅功能用多线程来实现,给 ...

  2. python 实现redis订阅发布功能

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  3. python redis 订阅发布_python 实现redis订阅发布功能

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  4. Redis的订阅发布功能对比RabbitMQ消息队列

    1.对比 特性 redis RabbitMQ 可靠性 没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中 具有消息消费确认机制,如果发布一 ...

  5. PHP 简易聊天室 利用redis的订阅发布功能

    demo: http://www.200ok.fun:8083/api/chat/list 前言: 这个种方式太耗redis连接数,每次订阅都会新起一个进程,仅供练手使用,切勿用于生产环境. 原理: ...

  6. MSSQLSERVER订阅发布闭坑指南

    SqlServer的订阅发布功能可以准实时的备份数据库,用来做读写分离都是可以的,简单好用 以下是亲身经历闭坑指南 准备工作 1,确定安装了数据库的复制功能,如果没有重新运行数据库安装包就可以增加这个 ...

  7. [Java]SpringBoot2整合mqtt服务器EMQ实现消息订阅发布入库(二)

    又到了显摆分享技术的时候了 没有看过上一篇文章的可以先看一下,这篇是在上一篇基础上接着添加功能 SpringBoot2整合mqtt服务器EMQ实现消息订阅发布入库(一) 这篇文章的流程为: 1.Spr ...

  8. java发布后功能不能用,急项目发布后java写的打印功能失效了-求解解决方法

    当前位置:我的异常网» J2EE » 急项目发布后java写的打印功能失效了-求解解决方法 急项目发布后java写的打印功能失效了-求解解决方法 www.myexceptions.net  网友分享于 ...

  9. Java设计模式-观察者模式(订阅发布模式)

    Java设计模式-观察者模式(订阅发布模式) 一起来看 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一起坚持吧!! ...

最新文章

  1. ASP.NET MVC Framework 系列
  2. C++实现平衡二叉树
  3. python爬虫背景_利用Python代码实现一键抠背景功能
  4. Python 中 pass的使用
  5. Openfire配置过程,以及与php交互注意事项。
  6. 【AAAI 2018】腾讯 AI Lab 11篇论文精选:图像描述、NMT 模型、图卷积神经网络、DNN优化等
  7. C#中的修饰符及其说明
  8. 云小课 | 守护网络安全不是问题,iptables的四表五链为你开启“八卦阵”
  9. ubuntu16.04 安装apache2报错 解决方案
  10. Nginx 日志配置实践
  11. 前后端分离项目,标准json协议格式参考
  12. Mysql 按 create_time 排序导致的问题
  13. 恒强制版系统980_恒功率、大功率及无线充电,充电设备面临哪些趋势和挑战?...
  14. android 歌词 开源,NLyric 网易云音乐歌词自动搜索下载【开源】
  15. 计算机图片文档怎么着,【电脑知识】怎样将图片转换成word文档
  16. python 节气_Python开源日志01:pyGregorian2LunarCalendar公历农历转换、阳历阴历转换、二十四节气计算...
  17. 线性代数【18】点积和对偶性
  18. 机器人大冒险(能否到达终点)
  19. 阿尔弗雷德.爱因斯坦论莫扎特钢协
  20. 为什么说继承是把双刃剑

热门文章

  1. 服务器装什么操作系统好?
  2. uniapp使用Dplayer.js实现视频播放
  3. 什么是信噪比?信噪比越大好还是越小好?
  4. python 将函数封装成pyd或者so文件,调用该文件
  5. 阿里云服务器 之 mqtt服务器搭建及使用
  6. 外包?第一份软件测试工作就一路高歌猛进,读书学Z渣一个现在生龙活虎
  7. 【redis】SpringBoot整合+geo地理位置应用
  8. 医学统计学 第七章(假设检验)
  9. redhat linux光盘4,技巧:把3张Redhat Linux 9的安装光盘刻录到一张DVD光盘中
  10. js:如何监听history的pushState方法和replaceState方法。(高阶函数封装+自定义事件)