设计模式--发布者与订阅者

2024-06-20 16:38

本文主要是介绍设计模式--发布者与订阅者,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring实现的发布者与订阅者  是观察者设计模式的一个扩展。

观察者设计模式

 

           目标

          观察者

          事件

三者之间是耦合在一起的,目标里面包含观察者的集合,观察者需要自己注入到目标中,当目标发生变化的时候,则会通知观察者集合,完成不同观察者的操作

 

 

发布者与订阅者的设计模式

 

发布者  订阅者  事件 事件通道

使用事件通道进行解决耦合的问题

Spring默认带有这个发布者关系

发布者 ApplicationContext

订阅者:@EventListener  ApplicationEventListener

事件:ApplicationEvent

通道:ApplicationEventMulticaster

一个使用Spring的demo

package designpattern.publisherandsubscribe;import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;@ComponentScan
public class Test {public static void main(String[] args){ApplicationContext context=new AnnotationConfigApplicationContext(Test.class);Test app=context.getBean(Test.class);RegisterService registerService=(RegisterService)context.getBean(RegisterService.class);registerService.regiesterUser();}
}
package designpattern.publisherandsubscribe;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.task.SimpleAsyncTaskExecutor;@Configuration
public class AsyncEventConfig {@Bean(name = "applicationEventMulticaster")public ApplicationEventMulticaster simpleApplicationEventMulticaster() {SimpleApplicationEventMulticaster eventMulticaster= new SimpleApplicationEventMulticaster();eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());return eventMulticaster;}
}
package designpattern.publisherandsubscribe;public interface EmailService {void sendEmail();
}
package designpattern.publisherandsubscribe;import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;@Service
public class EmailServiceImpl implements EmailService {@Overridepublic void sendEmail() {System.out.println("send email");}@EventListenerpublic void receiveTradeEvent(TradeEvent<OrderModel> tradeEvent){OrderModel orderModel=tradeEvent.getEventData();System.out.println(orderModel.getOrderId()+"--"+orderModel.getCreateTime());System.out.println(Thread.currentThread().getId()+"--"+Thread.currentThread().getName());this.sendEmail();}}
package designpattern.publisherandsubscribe;public interface MobileService {String sendTelephone();
}
package designpattern.publisherandsubscribe;import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;@Service
public class MobileServiceImpl implements MobileService {@Overridepublic String sendTelephone() {System.out.println("发短信");return null;}@EventListenerpublic void receiveTradeEvent(TradeEvent<OrderModel> tradeEvent){OrderModel orderModel=tradeEvent.getEventData();System.out.println(orderModel.getOrderId()+"--"+orderModel.getCreateTime());System.out.println(Thread.currentThread().getId()+"--"+Thread.currentThread().getName());this.sendTelephone();}
}
package designpattern.publisherandsubscribe;import java.util.Date;public class OrderModel {private String orderId;private Date createTime;public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}
}
package designpattern.publisherandsubscribe;public interface RegisterService {public void regiesterUser();
}
package designpattern.publisherandsubscribe;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.Date;@Service
public class RegisterServiceImpl implements RegisterService, ApplicationContextAware {private ApplicationContext applicationContext;@Override@Transactionalpublic void regiesterUser() {System.out.println("register user info to DB");OrderModel orderModel=new OrderModel();orderModel.setOrderId("111");orderModel.setCreateTime(new Date());applicationContext.publishEvent(new TradeEvent<OrderModel>(orderModel));System.out.println(Thread.currentThread().getId()+"--"+Thread.currentThread().getName());}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext=applicationContext;}
}
package designpattern.publisherandsubscribe;import org.springframework.context.ApplicationEvent;public class TradeEvent<T> extends ApplicationEvent {private T eventData;public TradeEvent(T source) {super(source);this.eventData=source;}public T getEventData() {return eventData;}public void setEventData(T eventData) {this.eventData = eventData;}
}

第二种发布者与订阅者的实现:分布式环境下的  消息中间件的使用,可以完成发布者和订阅者之间的关系,开源的产品notify,metaq,rocketmq,kafka。这些中间件还有一些其它的能力,比如发送消息和订阅消息,削峰填谷的能力,队列

 

第三种就是zookeeper的能力,也有发布订阅的能力。一个简单的case就是 如何实现DB热替换ip不宕机的需求

那就需要把配置文件的信息存储到 zookeeper的集群中,然后应用读取配置文件从zookeeper中读取,然后访问DB。应用程序需要启动zooker的客户端,连接zookeeper的服务端。

zookeeper还可以完成分布式锁,发布者和订阅者,领导选举等一些分布式的特性

这篇关于设计模式--发布者与订阅者的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1078683

相关文章

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

从《深入设计模式》一书中学到的编程智慧

软件设计原则   优秀设计的特征   在开始学习实际的模式前,让我们来看看软件架构的设计过程,了解一下需要达成目标与需要尽量避免的陷阱。 代码复用 无论是开发何种软件产品,成本和时间都最重要的两个维度。较短的开发时间意味着可比竞争对手更早进入市场; 较低的开发成本意味着能够留出更多营销资金,因此能更广泛地覆盖潜在客户。 代码复用是减少开发成本时最常用的方式之一。其意图

[最全]设计模式实战(一)UML六大原则

UML类图 UML类图是学习设计模式的基础,学习设计模式,主要关注六种关系。即:继承、实现、组合、聚合、依赖和关联。 UML类图基本用法 继承关系用空心三角形+实线来表示。实现接口用空心三角形+虚线来表示。eg:大雁是最能飞的,它实现了飞翔接口。 关联关系用实线箭头来表示。当一个类"知道"另一个类时,可以用关联。eg:企鹅需要"知道"气候的变化,需要"了解"气候规律。 聚合关

设计模式学习之中介者模式

我们平时写代码的过程,一个类必然会与其他类产生依赖关系,如果这种依赖关系如网状般错综复杂,那么必然会影响我们的代码逻辑以及执行效率,适当地使用中介者模式可以对这种依赖关系进行解耦使逻辑结构清晰,本篇博客,我们就一起学习中介者模式。 定义及使用场景 定义:中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使它们可以松散耦合。当某些对象之间的作用发生改变时,不会立即影响其

设计模式学习之模版方法模式

模板方法模式是一种基于继承的代码复用的行为型模式;在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。本篇博客我们一起来学习模版方法模式。 定义与UML图 定义 模板方法模式:定义一个操作

Android设计模式学习之Builder模式

Android设计模式学习之观察者模式 建造者模式(Builder Pattern),是创造性模式之一,Builder 模式的目的则是为了将对象的构建与展示分离。Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程。 模式的使用场景 1.相同的方法,不同的执行顺序,产生不同的事件结果时; 2.多个部件或零件,都可

【设计模式-04】原型模式

【设计模式-04】原型模式 1. 概述2. 结构3. 实现4. 案例5. 使用场景6. 优缺点6.1 原型模式的优点6.2 原型模式的缺点 7. 实现深克隆(深拷贝) 1. 概述 原型模式: 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。 2. 结构 原型模式包含如下角色: 抽象原型类:规定了具体原型对象必须实现的 clone() 方法。

redis 订阅/发布

本系列已经过半了,这一篇我们来看看redis好玩的发布订阅模式,其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果博主发表了文章,那么100个人就会同时收到通知邮件,除了这个 场景还能找到其他场景么,当然有啦,你想想,如果你要在内存里面做一个读写分离的程序,为了维持数据的完整性,你是不是需要保证在写

【database2】redis:优化/备份/订阅

文章目录 1.redis安装:加载.conf2.操作:set/get,push/pop,add/rem3.Jedis:java程序连接redis,拿到jedis4.案例_好友列表:json = om.4.1 前端:index.html4.2 web:FriendServlet .java4.3 service:FriendService.java4.4 dao:FriendDao.java4

Java中常见的设计模式及应用场景

Java中常见的设计模式及应用场景 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨Java中常见的设计模式及其应用场景,帮助大家更好地理解和应用这些设计模式,提高代码的可维护性和可扩展性。 设计模式概述 设计模式是一种被反复使用的、经过分类的、代码设计中被广泛认可的优秀代码设计经验。它不仅能解决常见的问题,还能