课程标题《spring事件监听的观察者模式源码分析》
课程内容:
1.什么是观察者模式?
2.观察者模式优缺点
3.什么是事件监听
4.spring事件监听源码解读
5.jdk自带观察者模式源码解读

什么是观察者模式

在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

Spring封装事件监听

Spring封装事件监听

例如用户注册成功之后,会发送邮件和短信

package com.mayikt.service;import com.mayikt.service.entity.MsgEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/**
* @author 余胜军
* @ClassName MayiktService
* @qq 644064779
* @addres www.mayikt.com
* 微信:yushengjun644
*/
@RestController
@Slf4j
public class MayiktService {@Autowiredprivate ApplicationContext applicationContext;/*** 注册代码** @return*/@RequestMapping("/register")public String register() {log.info("register...");// 发送短信、发送邮件、发送微信公众号// sendMsg();// sendEmail();// sendWechatTemplate();MsgEntity msgEntity =new MsgEntity(this, "18140668851", "644064@qq.com","wx123456", "dingding123456");applicationContext.publishEvent(msgEntity);return "ok";}}
package com.mayikt.service.entity;import lombok.Data;
import org.springframework.context.ApplicationEvent;/*** @author 余胜军* @ClassName MsgEntity* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Data
public class MsgEntity  extends ApplicationEvent {// 手机号码private String phone;// 邮件private String email;// 微信openidprivate String weChatOpenId;/*** 钉钉openid*/private String dindinOpenId;public MsgEntity(Object source, String phone, String email, String weChatOpenId, String dindinOpenId) {super(source);this.phone = phone;this.email = email;this.weChatOpenId = weChatOpenId;this.dindinOpenId = dindinOpenId;}@Overridepublic String toString() {return "MsgEntity{" +"phone='" + phone + '\'' +", email='" + email + '\'' +", weChatOpenId='" + weChatOpenId + '\'' +", dindinOpenId='" + dindinOpenId + '\'' +'}';}
}
package com.mayikt.service.listener;import com.mayikt.service.entity.MsgEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;/*** @author 余胜军* @ClassName WeChat* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Slf4j
@Component
public class WeChatMessageListener implements ApplicationListener<MsgEntity> {@Overridepublic void onApplicationEvent(MsgEntity event) {// 发送微信log.info("<发送微信:{}>", event.toString());}
}package com.mayikt.service.listener;import com.mayikt.service.entity.MsgEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;/*** @author 余胜军* @ClassName TextMessageListener* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Component
@Slf4j
public class TextMessageListener implements ApplicationListener<MsgEntity> {@Overridepublic void onApplicationEvent(MsgEntity event) {log.info("<发送短信:{}>", event.toString());}
}@Autowiredprivate ApplicationContext applicationContext;@RequestMapping("/login")public String login() {log.info("login...");// 1.步骤1:验证数据库信息(手机号码、密码) //1// 2.步骤2: 发送登录短信、邮件、公众号模板、赠送优惠卷、发送钉钉// 发送短信、发送邮件、发送微信公众号
//        sendMsg(); // 1s
//        sendEmail(); // 1s
//        sendWechatTemplate(); // 1s//send发送优惠券
//        sendDinDin();MsgEntity msgEntity =new MsgEntity(this, "18140668851", "644064@qq.com","wx123456", "dingding123456");applicationContext.publishEvent(msgEntity);// 给我们的每个观察者发送内容return "ok";}

整合线程池异步方式

package com.mayikt.service.listener;import com.mayikt.service.entity.MsgEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;/*** @author 余胜军* @ClassName TextMessageListener* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Component
@Slf4j
public class TextMessageListener implements ApplicationListener<MsgEntity> {@Override@Asyncpublic void onApplicationEvent(MsgEntity event) {log.info("<发送短信:{}>", event.toString());}
}package com.mayikt.service.listener;import com.mayikt.service.entity.MsgEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;/*** @author 余胜军* @ClassName WeChat* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Slf4j
@Component
public class WeChatMessageListener implements ApplicationListener<MsgEntity> {@Override@Asyncpublic void onApplicationEvent(MsgEntity event) {// 发送微信log.info("<发送微信:{}>", event.toString());}
}

观察者模式应用场景

Zookeeper事件通知节点、消息订阅通知、安卓开发事件注册、分布式配置中心。

1.抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

2.抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

3.具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。

4.具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。

使用观察者群发邮件、短信

抽象观察者

public interface ObServer {/*** 更新消息内容** @param message* @return*/public void update(String message);}

抽象主题

package com.mayikt.obServer;/*** @author 余胜军* @ClassName AbstractSubject* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
public interface AbstractSubject {/*** 新增addObServer*/void addObServer(ObServer obServer);/*** 删除数据*/void removeObServer(ObServer obServer);/*** 通知所有的ObServerAll*/void notifyObServerAll(String message);
}

具体主题

package com.mayikt.obServer.impl;import com.mayikt.obServer.AbstractSubject;
import com.mayikt.obServer.ObServer;import java.util.ArrayList;
import java.util.List;/*** @author 余胜军* @ClassName MsgSubject* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
public class MsgSubject implements AbstractSubject {// 发送消息主题private List<ObServer> obServers = new ArrayList<>();@Overridepublic void addObServer(ObServer obServer) {obServers.add(obServer);}@Overridepublic void removeObServer(ObServer obServer) {obServers.remove(obServer);}@Overridepublic void notifyObServerAll(String message) {// 循环遍历调用,每个ObServerobServers.forEach((o) -> {// 调用updateo.update(message);});}
}

具体观察者

package com.mayikt.obServer.impl;import com.mayikt.obServer.ObServer;
import lombok.extern.slf4j.Slf4j;/*** @author 余胜军* @ClassName WeChatObServerImpl* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Slf4j
public class WeChatObServer implements ObServer {@Overridepublic void update(String message) {log.info("发送微信模板消息:{}", message);}
}package com.mayikt.obServer.impl;import com.mayikt.obServer.ObServer;
import lombok.extern.slf4j.Slf4j;/*** @author 余胜军* @ClassName TextMessageObServer* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Slf4j
public class TextMessageObServer  implements ObServer {@Overridepublic void update(String message) {log.info("发送短信消息:{}", message);}
}

责任链与观察者模式区别

责任链 有严格顺序、多个观察者(没有顺序要求)

运行测试

package com.mayikt.obServer;import com.mayikt.obServer.impl.MsgSubject;
import com.mayikt.obServer.impl.TextMessageObServer;
import com.mayikt.obServer.impl.WeChatObServer;/*** @author 余胜军* @ClassName Test01* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
public class Test01 {public static void main(String[] args) {ObServer textMessageObServer = new TextMessageObServer();ObServer weChatObServer = new WeChatObServer();MsgSubject msgSubject = new MsgSubject();msgSubject.addObServer(textMessageObServer);msgSubject.addObServer(weChatObServer);msgSubject.notifyObServerAll("mayikt");}
}

JDK自带封装的观察者

(1). Observable类追踪所有的观察者,并通知他们。
(2). Observer这个接口看起来很熟悉,它和我们之前写的类几乎一样。
package com.mayikt.obServer.jdk;import java.util.Observable;/*** @author 余胜军* @ClassName MessageObServable* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
public class MessageObServable extends Observable  {@Overridepublic void notifyObservers(Object obj) {// 1.改变数据setChanged();// 2.通知所有观察者改变super.notifyObservers(obj);}
}package com.mayikt.obServer.jdk.impl;import com.mayikt.obServer.jdk.MessageObServable;
import lombok.extern.slf4j.Slf4j;import java.util.Observable;
import java.util.Observer;/*** @author 余胜军* @ClassName EmailObServer* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Slf4j
public class EmailObServer implements Observer {@Overridepublic void update(Observable o, Object arg) {// 1.获取主题MessageObServable MessageObServable= (MessageObServable) o;log.info("获取到发送的邮件内容:"+arg);}
}package com.mayikt.obServer.jdk.impl;import com.mayikt.obServer.jdk.MessageObServable;
import lombok.extern.slf4j.Slf4j;import java.util.Observable;
import java.util.Observer;/*** @author 余胜军* @ClassName EmailObServer* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
@Slf4j
public class TextMessageObServer implements Observer {@Overridepublic void update(Observable o, Object arg) {// 1.获取主题MessageObServable MessageObServable = (MessageObServable) o;log.info("获取到发送的短信内容:" + arg);}
}package com.mayikt.obServer.jdk.impl;import com.mayikt.obServer.jdk.MessageObServable;/*** @author 余胜军* @ClassName Test01* @qq 644064779* @addres www.mayikt.com* 微信:yushengjun644*/
public class Test01 {public static void main(String[] args) {MessageObServable messageObServable = new MessageObServable();messageObServable.addObserver(new TextMessageObServer());messageObServable.addObserver(new EmailObServer());messageObServable.notifyObservers("mayikt");;}
}

相关代码

06.设计模式之观察者模式相关推荐

  1. 设计模式:观察者模式--Observer

    一.什么是观察者模式 1.生活中的观察者模式 1.警察抓小偷 在现实生活中,警察抓小偷是一个典型的观察者模式「这以一个惯犯在街道逛街然后被抓为例子」,这里小偷就是被观察者,各个干警就是观察者,干警时时 ...

  2. java 观察者模式_图解Java设计模式之观察者模式

    图解Java设计模式之观察者模式 天气预报项目需求 天气预报设计方案 1 - 普通方案 观察者模式(Observer)原理 观察者模式解决天气预报需求 观察者模式在JDK应用的源码分析 天气预报项目需 ...

  3. 游戏服务器架构-设计模式之观察者模式和发布订阅模式真的一样吗?

    前面我给大家分享了观察者模式和发布订阅模式,有人私信给我说这俩不是一样嘛,大体没什么区别,我猜测大多数认为这两者是一样的可以继续阅读这两篇文章,如果还不能解答你的问题,我相信这篇文章对比两者的关系会让 ...

  4. java设计模式观察者模式吗_Java设计模式之观察者模式原理与用法详解

    Java设计模式之观察者模式原理与用法详解 本文实例讲述了Java设计模式之观察者模式原理与用法.分享给大家供大家参考,具体如下: 什么是观察者模式 可以这么理解: 观察者模式定义了一种一对多的依赖关 ...

  5. 设计模式 C++观察者模式

    无论是在现实世界中还是在软件系统中,人们常常会遇到这样一类问题,一个对象的状态改变会引发其他对象的状态改变,如十字路口的交通信号灯,红灯亮则汽车停,绿灯亮则汽车行,再如点击软件中一个按钮,则会弹出一个 ...

  6. 学习《图说设计模式》观察者模式

    图说设计模式之观察者模式 1. 模式动机 建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应.在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一 ...

  7. 设计模式之观察者模式——猫抓老鼠2

    设计模式之观察者模式--猫抓老鼠2: 对猫抓老鼠1再次进行优化,降低代码复杂性,以及使用事件来对方法进行保护 代码优化: 将老鼠代码进行优化,将自己的方法在构造时便注册到猫里面: using Syst ...

  8. 设计模式之观察者模式——猫抓老鼠1

    设计模式之观察者模式--猫抓老鼠: 问题描述: 通过猫抓老鼠的例子进行了解观察者模式,首先的初始代码为(有三个类): using System;/// <summary> /// 观察者设 ...

  9. 设计模式学习--观察者模式(Observer Pattern)

    设计模式学习--观察者模式(Oberser Pattern) 2013年5月18日 天气:热!  下午15:28  设计模式学习中 学习者:小巫 什么是观察者模式? 定义了对象之间的一对多依赖,这样一 ...

最新文章

  1. 2011年的总结:Fans同学的成败得失
  2. java从键盘输入数据斐波那契数_从键盘输入一个正整数n,打印出斐波那契数列的前n个元素...
  3. SharePoint 2013 自定义扩展菜单(二)
  4. Spring经典面试题
  5. 即时通讯成为热门传播媒体
  6. 第八章 丹药吃坏人了
  7. Java poi 列移动_如何在java xssf中移動列poi
  8. 【python】字符串的操作与方法、元组的定义与操作
  9. xmind怎样画流程图_老师是怎样上网课的?
  10. Redis for Windows
  11. iOS 用自签名证书实现 HTTPS 请求的原理
  12. WinAPI: Rectangle - 绘制矩形
  13. php 获取刚插入的一条,php获得刚插入数据的id 的几种方法
  14. 福利 | 简历模板大放送
  15. B2B电商平台--ChinaPay银联电子支付功能
  16. 王道计算机网络学习笔记
  17. 保研面试-中英文问题及回答总结
  18. UE4创建VR项目笔记
  19. 如何看懂这些图形学公式
  20. AVFrame相关api内存管理

热门文章

  1. 退出cmd.exe或退出批处理文件
  2. Oracle日期函数add_months()、last_day()、months_between()的用法
  3. 联想小新使用Alt+insert快捷键
  4. 在手机安装 Kali Linux
  5. Maven中scope标签详解
  6. 该设备正在使用中。请关闭可能使用该设备的所有程序或窗口,然后重试。
  7. 经典CNN模型介绍及Pytorch实现
  8. Python海龟绘图,画花朵
  9. 【数学建模】基于matlab武汉地铁2号线路线地图动态模拟【含Matlab源码 1092期】
  10. 导入EXCEL2007报错外部表不是预期的格式错误