观察者模式实际应用场景-----Spring事件机制
2019-01-10 12:46
741 查看
以下伪代码是一个保存订单的功能,并会发送短信消息:
[code]/** * Author heling on 2019/1/9 */ @Service public class OrderServiceImpl implements OrderService { @Override public void saveOrder() { //1.创建订单 System.out.println("订单创建成功"); //2.发送短信 System.out.println("恭喜您订单创建成功!----by sms"); } }
现有新需求:需要加一个微信通知的功能,代码如下:
[code]/** * Author heling on 2019/1/9 */ @Service public class OrderServiceImpl implements OrderService { @Override public void saveOrder() { //1.创建订单 System.out.println("订单创建成功"); //2.发送短信 System.out.println("恭喜您订单创建成功!----by sms"); //新需求:微信通知 // 3.发送微信 System.out.println("恭喜您订单创建成功!----by wechat"); } }
存在问题:每次创建订单需要加新功能(如新的通知方式),则要修改原有的类,难以维护。
违背设计模式的原则
1.单一职责:订单保存功能,杂糅了消息通知这些功能
2.开闭原则:对拓展开放,对修改关闭
优化方案:使用观察者模式,使创建订单和消息通知进行分离,低耦合。可以选择消息队列,spring事件机制等,本文选择Spring事件机制。
改造开始:
1.创建事件
[code]package com.pengshu.magicwallet.admin.test; import org.springframework.context.ApplicationEvent; import java.util.List; /** * Author heling on 2019/1/9 * 订单创建活动事件 */ public class OrderCreateEvent extends ApplicationEvent { private String name; //消息参数 private List<String> contentList; public OrderCreateEvent(Object source, String name, List<String> contentList) { super(source); this.name = name; this.contentList = contentList; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getContentList() { return contentList; } public void setContentList(List<String> contentList) { this.contentList = contentList; } }
2.监听器
[code]package com.pengshu.magicwallet.admin.test; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * Author heling on 2019/1/9 * 短信监听器 * ApplicationListener是无序的 */ @Component public class SmsListener implements ApplicationListener<OrderCreateEvent> { @Override public void onApplicationEvent(OrderCreateEvent event) { //发送短信 System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by sms"); } }
[code]package com.pengshu.magicwallet.admin.test; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * Author heling on 2019/1/9 * 微信监听器 */ @Component public class WechatListener implements ApplicationListener<OrderCreateEvent> { @Override public void onApplicationEvent(OrderCreateEvent event) { //发送微信 System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by wechat"); } }
3.事件发布
[code]package com.pengshu.magicwallet.admin.test; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; /** * Author heling on 2019/1/9 */ @Service public class OrderServiceImpl implements OrderService { @Resource private ApplicationContext applicationContext; @Autowired private ApplicationEventPublisher applicationEventPublisher; @Override public void saveOrder() { //1.创建订单 System.out.println("订单创建成功"); //2.发布事件 ArrayList<String> contentList = new ArrayList<>(); contentList.add("heling"); contentList.add("123456789"); OrderCreateEvent orderCreateEvent = new OrderCreateEvent(this, "订单创建", contentList); applicationContext.publishEvent(orderCreateEvent);//ApplicationContext是我们的事件容器上层,我们发布事件,也可以通过此容器完成发布 //applicationEventPublisher.publishEvent(orderCreateEvent);//也可以 System.out.println("finished!"); } }
打印结果:
订单创建成功
heling,您的订单:123456789创建成功! ----by sms
heling,您的订单:123456789创建成功! ----by wechat
finished!
如何异步执行监听器?
1.springboot开启事件异步设置
[code]package com.pengshu.magicwallet; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.PropertySource; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication @MapperScan("com.pengshu.magicwallet.mapper") @PropertySource("classpath:authority.properties") @EnableTransactionManagement @EnableAsync //开启spring事件异步设置,加@Async注解 public class MagicWalletAdminApplication { public static void main(String[] args) { SpringApplication.run(MagicWalletAdminApplication.class, args); } }
2.监听器类或方法添加@Async注解
打印结果:
订单创建成功
finished!
heling,您的订单:123456789创建成功! ----by sms
heling,您的订单:123456789创建成功! ----by wechat
如何制定监听器执行顺序?
[code]package com.pengshu.magicwallet.admin.test; import org.springframework.context.ApplicationEvent; import org.springframework.context.event.SmartApplicationListener; import org.springframework.stereotype.Component; /** * Author heling on 2019/1/9 * 微信监听器 * SmartApplicationListener可以设置顺序等 */ @Component public class WechatListener implements SmartApplicationListener { //设置监听优先级 @Override public int getOrder() { return 1; } //监听器智能所在之一,能够根据事件类型动态监听 @Override public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) { return aClass == OrderCreateEvent.class; } //监听器智能所在之二,能够根据事件发布者类型动态监听 @Override public boolean supportsSourceType(Class<?> aClass) { return aClass == OrderServiceImpl.class; } @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { OrderCreateEvent event = (OrderCreateEvent) applicationEvent; //发送微信 System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by wechat"); } // @Override // @Async // public void onApplicationEvent(OrderCreateEvent event) { // // //发送微信 // System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by wechat"); // // } }
[code]package com.pengshu.magicwallet.admin.test; import org.springframework.context.ApplicationEvent; import org.springframework.context.event.SmartApplicationListener; import org.springframework.stereotype.Component; /** * Author heling on 2019/1/9 * 短信监听器 */ @Component public class SmsListener implements SmartApplicationListener { @Override public int getOrder() { return 2; } @Override public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) { return aClass == OrderCreateEvent.class; } @Override public boolean supportsSourceType(Class<?> aClass) { return aClass == OrderServiceImpl.class; } @Override public void onApplicationEvent(ApplicationEvent applicationEvent) { OrderCreateEvent event = (OrderCreateEvent) applicationEvent; //发送短信 System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by sms"); } // @Override // @Async // public void onApplicationEvent(OrderCreateEvent event) { // // //发送短信 // System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by sms"); // // } }
打印结果:
订单创建成功
heling,您的订单:123456789创建成功! ----by wechat
heling,您的订单:123456789创建成功! ----by sms
finished!
在实现了SmartApplicationListener的监听器中,我们通过重写GetOrder方法来修改不同监听器的顺序,优先级越小,则越先被调用。通过配置不同的优先级,且让监听器之间阻塞调用。我们就能实现流水线式的有序事件调用,这在实际应用场景中还是蛮有意义的
相关文章推荐
- 15、Spring事件机制_观察者模式
- java事件监听机制(观察者设计模式的实际运用)
- unity学习——事件机制(观察者模式)
- java事件监听机制,spring中的event listener模式和解耦
- 观察者模式应用场景实例
- 【C#】Event事件的应用之观察者模式
- 观察者模式与事件监听机制
- 设计模式------观察者模式... ...事件委托机制...
- spring事件驱动模型--观察者模式在spring中的应用
- php观察者模式应用场景实例详解
- Android:图解四种启动模式 及 实际应用场景解说
- 事件机制 -- 典型观察者模式 js实现
- java设计模式--观察者模式应用场景
- Spring 设计模式——观察者|事件驱动模型
- IOC,观察者模式,项目的实际应用
- 设计模式-单例模式(Singleton)在Android中的应用场景和实际使用遇到的问题
- Android:图解四种启动模式 及 实际应用场景解说
- python 反射机制在实际的应用场景讲解
- Android之“观察者模式”解析及实际应用:"应用宝"软件下载中 进度条同步更新
- Java设计模式_观察者模式&事件处理机制