基于 观察者模式设置监听 || 及使用 listener监听实现,处理多渠道消息通知(短信+邮箱+公众号消息推送等)

tech2022-08-09  133

观察者描述

1、观察者模式基本概念

一个对象状态改变,通知给其他所有的对象

2、观察者模式的应用场景

Zk的事件监听、分布式配置中心刷新配置文件、业务中群发不同渠道消息

一、使用 观察者模式设置监听

使用 观察者模式 是异步执行的多渠道消息通知(短信+邮箱+公众号消息推送等)

1、 SpringUtils 工具类

/** * SpringUtils 工具类 */ @Component public class SpringUtils implements ApplicationContextAware { private static ApplicationContext applicationContext = null; public static ApplicationContext getApplicationContext() { return applicationContext; } public static <T> T getBean(String beanId) { return (T) applicationContext.getBean(beanId); } public static <T> T getBean(Class<T> requiredType) { return (T) applicationContext.getBean(requiredType); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtils.applicationContext = applicationContext; } }

2、创建观察者接口

/** * 观察者接口 */ public interface ObServer { void sendMsg(JSONObject jsonObject); }

3、创建观察者一

@Component @Slf4j public class EmailObServer implements ObServer { @Override public void sendMsg(JSONObject jsonObject) { log.info("使用观察者发送邮件"); } }

4、创建观察者二

@Slf4j @Component public class SMSObServer implements ObServer { @Override public void sendMsg(JSONObject jsonObject) { log.info(“使用观察者发送短信”); } }

5、所有、观察者容器

import com.alibaba.fastjson.JSONObject; import com.xijia.xj.observer.ObServer; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 观察者容器, listObServer = 所有的观察类 * @author wangsong * @mail 1720696548@qq.com * @date 2020/9/2 0002 21:22 * @version 1.0.0 */ @Component public class XjSubject { /** * 类型 ObServer */ private List<ObServer> listObServer = new ArrayList<>(); /** * 线程池 */ private ExecutorService executorService; public XjSubject() { executorService = Executors.newFixedThreadPool(10); } /** * 新增ObServer * * @param obServer */ public void addObServer(ObServer obServer) { listObServer.add(obServer); } /** * 通知给所有的观察者,遍历执行所有观察者的方法 * * @param jsonObject */ public void notifyObServer(JSONObject jsonObject) { for (ObServer obServer : listObServer) { // 单独开启线程异步通知 executorService.execute(new Runnable() { @Override public void run() { obServer.sendMsg(jsonObject); } }); } } }

6、自动注册所有观察者 到 观察者容器中

import com.xijia.xj.config.SpringUtils; import com.xijia.xj.observer.ObServer; import com.xijia.xj.observer.subject.XjSubject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import java.util.Map; /** * 项目启动后需要 执行的一些方法 --> 注册观察者, 当我们的SpringBoot启动成功的时候,注册我们的SMSObServer * @author wangsong * @mail 1720696548@qq.com * @date 2020/9/2 0002 21:27 * @version 1.0.0 */ @Component public class InitService implements ApplicationRunner { @Autowired private XjSubject xjSubject; @Override public void run(ApplicationArguments args) throws Exception { /** * 自动注册我们观察者 * 1.使用Spring获取该ObServer下有那些bean对象 * 2.直接注添加到集合中 */ //根据接口类型返回相应的所有bean Map<String, ObServer> map = SpringUtils.getApplicationContext().getBeansOfType(ObServer.class); for (String key : map.keySet()) { ObServer obServer = map.get(key); xjSubject.addObServer(obServer); } } }

7、使用观察者模式

@RestController @Slf4j public class OrderService { @Autowired private XjSubject xjSubject; @RequestMapping("/addOrder") public String addOrder() { log.info("1.调用数据库下单订单代码:"); JSONObject jsonObject = new JSONObject(); jsonObject.put("sms", "1865891111"); jsonObject.put("email", "644064779@qq.com"); xjSubject.notifyObServer(jsonObject); return "success"; } }

8、执行效果

二、使用 spring 的 Listener 监听

注意 spring 的 Listener 是同步执行的,不支持@Async 异步注解

1、创建监听传递的,参数类

package com.xijia.spring.entity; import org.springframework.context.ApplicationEvent; public class UserMessageEntity extends ApplicationEvent { private String email; private String phone; private String userId; /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ 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; } }

2、创建监听1(观察者1)

/** * 监听发送邮件 */ @Component public class EmailListener implements ApplicationListener<UserMessageEntity> { /** * 监听的方法 * * @param event */ @Override @Async public void onApplicationEvent(UserMessageEntity event) { System.out.println(Thread.currentThread().getName() +" 邮件:" + event.toString()); } }

3、创建监听2(观察者2)

/** * 监听发送邮件 */ @Component public class SmSListener implements ApplicationListener<UserMessageEntity> { /** * 监听的方法 * * @param event */ @Override @Async public void onApplicationEvent(UserMessageEntity event) { System.out.println(Thread.currentThread().getName() + " 短信:" + event.toString()); } }

4、使用Listener 监听

@RestController @Slf4j public class OrderService { @RequestMapping("/addOrder2") public String addOrder2() { log.info("1.调用数据库下单订单代码:"); UserMessageEntity userMessageEntity = new UserMessageEntity(this, "644064779@qq.com", "1865891111"); applicationEventPublisher.publishEvent(userMessageEntity); return "success"; } }

5、执行效果

以上部分内容出自于蚂蚁课堂 http://www.mayikt.com/

个人开源项目(通用后台管理系统)–> https://gitee.com/wslxm/spring-boot-plus2 , 喜欢的可以看看

本文到此结束,如果觉得有用,动动小手点赞或关注一下呗,将不定时持续更新更多的内容…,感谢大家的观看!

最新回复(0)