本文主要是介绍设计模式--发布者与订阅者,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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还可以完成分布式锁,发布者和订阅者,领导选举等一些分布式的特性
这篇关于设计模式--发布者与订阅者的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!