- 1 观察者模式课程内容的引入
- 2 观察者模式介绍
- 3 观察者模式类图结构的分析
- 4 定义观察者模式的接口
- 5 项目启动注册读观察者(自动注册)
- 6 测试手写观察者模式
- 7 使用Spring事件监听实现观察者
课程内容
- 观察者模式基本的observer概念
- 观察者模式在实际开发中的应用场景
- 如何基于观察者模式设计多渠道群发框架
- ApplicationListener事件监听原理
观察者基本概念
当一个对象发生改变的时候可以通知给其他所有的对象
观察者应用场景
- zk临时节点监听(当zk临时节点发生变化,会通知给所有客户端)
- 分布式配置中心 nacos、config、携程Apollo刷新配置文件
- 多渠道群发
addOrder(){
// 1.向数据库中插入订单数据
// 2.发送短信代码
// 3.发送邮件代码
// 4.发送微信代码
}
==》观察者模式一行代码封装
public interface ObServer {
void sendMsg(JSonObject jsonObject);
}
@Component
@Slf4j
public class SmsObServer implements ObServer {
@Override
public void sendMsg(JSonObject jsonObject) {
log.info("使用观察者发送短信");
}
}
@Component
@Slf4j
public class EmailObServer implements ObServer {
@Override
public void sendMsg(JSonObject jsonObject) {
log.info("使用观察者发送邮件");
}
}
@Component
public class MayiktSubject {
private List listObServer = new ArrayList<>();
private ExecutorService executorService;
public MayiktSubject() {
executorService = Executors.newFixedThreadPool(10);
}
public void addObServer(ObServer obServer) {
listObServer.add(obServer);
}
public void notifyObServer(JSonObject jsonObject) {
for (ObServer obServer : listObServer) {
// 单独开启线程异步通知
executorService.execute(() -> obServer.sendMsg(jsonObject));
}
}
}
5 项目启动注册读观察者(自动注册)
@Component
public class StartService implements ApplicationRunner, ApplicationContextAware {
@Autowired
private SmsObServer smsObServer;
@Autowired
private EmailObServer emailObServer;
@Autowired
private MayiktSubject mayiktSubject;
private ApplicationContext applicationContext;
// 当SpringBoot启动成功之后,再注册SmsObServer和EmailObServer
@Override
public void run(ApplicationArguments args) throws Exception {
// mayiktSubject.addObServer(smsObServer);
// mayiktSubject.addObServer(emailObServer);
// 使用java反射机制获取ObServer下所有子类自动注册到集合中
// 根据接口类型返回相应的所有bean
Map map = applicationContext.getBeansOfType(ObServer.class);
for (String key : map.keySet()) {
ObServer obServer = map.get(key);
mayiktSubject.addObServer(obServer);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
6 测试手写观察者模式
@RestController
@Slf4j
public class OrderService {
@Autowired
private MayiktSubject mayiktSubject;
@RequestMapping("/addOrder")
public String addOrder() {
log.info("1.调用数据库下单订单代码:");
JSonObject jsonObject = new JSONObject();
jsonObject.put("sms", "1865891111");
jsonObject.put("email", "644064779@qq.com");
mayiktSubject.notifyObServer(jsonObject);
return "success";
}
}
运行结果:
定义消息实体类
@Data
public class UserMessageEntity extends ApplicationEvent {
private String email;
private String phone;
private String userId;
public UserMessageEntity(Object source) {
super(source);
}
public UserMessageEntity(Object source, String email, String phone) {
super(source);
this.email = email;
this.phone = phone;
}
@Override
public String toString() {
return "email:" + email + ",phone:" + phone;
}
}
定义事件通知
@Component @Slf4j public class EmailListener implements ApplicationListener{ @Override public void onApplicationEvent(UserMessageEntity event) { log.info("使用SpringBoot观察者发送邮件:" + event.getEmail()); } }
@Component @Slf4j public class SmsListener implements ApplicationListener{ @Override public void onApplicationEvent(UserMessageEntity event) { log.info("使用SpringBoot观察者发送短信:" + event.getPhone()); } }
发布事件
@RestController
@Slf4j
public class OrderService {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@RequestMapping("/addOrder2")
public String addOrder2() {
log.info("1.调用数据库下单订单代码:");
UserMessageEntity userMessageEntity = new UserMessageEntity(this, "644064779@qq.com", "1865891111");
applicationEventPublisher.publishEvent(userMessageEntity);
return "success";
}
}
运行结果:
源码下载地址(mayikt_designPattern_5.zip):
链接:https://pan.baidu.com/s/1wWKZN1MbXICZVW1Vxtwe6A
提取码:fire



