Springboot事件监听机制:实战应用
目录
前言
事件监听机制的定义
事件监听机制的应用场景
事件监听机制的好处
springboot事件监听机制的实现
总结
前言
事件监听机制是一套很有用的机制,其原理就是观察者模式,而观察者模式又被称为发布-订阅模式,有人说23种设计模式平时很少用上,总是看了忘,我只能说你太不走心了。我的经验就是一定要带着问题去学习新东西,设计模式不仅是一套理论,更是长期的工程实践总结出来经验、解决方案。想要掌握好,必须要弄清每一个设计模式的本质是为了解决什么问题。
1. 事件监听机制的定义
事件监听机制的本质是一套流程,这套流程描述的是某个位置发生了一些事,发生的这些事又触发了另外一些事。如果使用面向对象的思想对这套流程进行抽象,会抽象出来几个非常关键的类,分别是事件源、事件、监听器。
事件源:就是所谓的某个位置
事件:就是某个位置发生的一些事;
监听器:某个位置发生一些事后,被监听器知道了,又触发监听器的一些行为;
把这些片断信息连起来,就是在事件源产生事件,被监听器捕获,然后又触发了其他行为。
如果还是觉得抽象,举个例子:明朝的锦衣卫相信大家都非常熟悉,飞鱼服绣春刀的,帅得狠,当然这不是重点,重点是朱老总打下江山,总害怕乱臣贼子干坏事,于是乎创立了锦衣卫制度。那些老朱觉得危险的王侯、勋臣、大将军什么的,各家都派些锦衣卫盯着,每天吃喝了啥、写了啥文章、说了啥话、平时和那些人交往、收没收礼、有没有贪污、有没有不法行为,事无巨细都报到东厂来。老朱的这一套操作下来,就是一套事件监听机制。事件源就是那些被监视的对象,事件就是大臣们有没有不法行为,监听器就是大臣们家的不起眼小妾、仆人、丫鬟(没有飞鱼服、绣春刀的也有可能是锦衣卫),一旦这些大臣有啥不法事情马上会被报告到东厂,然后老朱就知道了,该处理处理。这就是事件监听机制,或者叫观察者模式、监听者模式,叫什么无所谓,本质是一样的。
2. 事件监听机制的应用场景
在程序设计里有哪些场景会用到呢?下面举一些例子: 用户注册成功了,得发个提示短信吧,用户下单成功迟迟不付款得发个提示短信吧,用户生日了得发送个祝福短信吧,这些都是比较简单的场景,简单抽象一下,用户的很多业务行为都会有要发短信的需求,如果每个业务行为都各自发短信,那么首先业务行为与发短信就耦合了,不利于后续扩展,其次具有相同特征的行为一直重复。使用事件监听机制改造一下,把各个业务行为内的短信内容封装成一个事件,业务行为触发的时候发布这个事件,再把具体发短信的行为封装到监听器里,监听到事件源发布的事件后,触发具体的发短信的行为。
3. 事件监听机制的好处
- 业务与业务之间解耦,符合依赖倒置原则;
- 代码复用,更容易维护,也提高了执行效率;
4. springboot事件监听机制的实现
作为spring家族的集大成者springboot其实已经事先预留好了相关的接口,只需要根据具体业务场景实现就可以使用了,下面主要用伪代码展示一下用法:
1、继承spring事件基类ApplicationEvent,完成事件的封装;
2、实现ApplicationListener接口,并通过@Component注解把事件监听器注册到spring容器里;
3、业务类要实现ApplicationEventPublisherAware接口,把spring的事件发布器注入到业务类里,在触发事件的时候,spring的事件发布器发布事件;
@Getter
@Setter
public class SmsEvent extends ApplicationEvent {
private String eventType="短信发送事件";
private String eventName;
private Map<String,Object> smsObj;
public SmsEvent(Object source) {
super(source);
}
}
@Component
public class SmsListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
if (applicationEvent instanceof SmsEvent) {
SmsEvent smsEvent = (SmsEvent) applicationEvent;
System.out.println("监听到事件名称:" + smsEvent.getEventName());
System.out.println("开始执行事件:" + smsEvent.getEventName());
Map<String, Object> smsObj = smsEvent.getSmsObj();
String userName = smsObj.get("userName").toString();
String phone = smsObj.get("phone").toString();
String msgContent = smsObj.get("msgContent").toString();
SmsUtil.sendMsg(userName, phone, msgContent);
}
}
}
@Component
public class UserService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void registe(){
System.out.println("新用户张三注册成功");
System.out.println("触发短信事件....");
Map<String,Object> smsObj=new HashMap<>();
smsObj.put("userName", "张三");
smsObj.put("phone","15503117788" );
smsObj.put("msgContent", "hello , 欢迎来到csdn");
SmsEvent smsEvent = new SmsEvent(this);
smsEvent.setSmsObj(smsObj);
smsEvent.setEventName("注册成功短信事件");
this.applicationEventPublisher.publishEvent(smsEvent);
}
public void orderedOfUnPay() {
System.out.println("张三下单成功,但是未付款");
Map<String,Object> smsObj=new HashMap<>();
smsObj.put("userName", "张三");
smsObj.put("phone","15503117788" );
smsObj.put("msgContent", "张三先生,你好!请尽快付款");
SmsEvent smsEvent = new SmsEvent(this);
smsEvent.setSmsObj(smsObj);
smsEvent.setEventName("下单成功未付款短信事件");
this.applicationEventPublisher.publishEvent(smsEvent);
}
public void birthdayGreeting(){
System.out.println("今天是张三生日,触发自动短信祝福业务");
Map<String,Object> smsObj=new HashMap<>();
smsObj.put("userName", "张三");
smsObj.put("phone","15503117788" );
smsObj.put("msgContent", "亲爱张三先生,祝你生日快乐");
SmsEvent smsEvent = new SmsEvent(this);
smsEvent.setSmsObj(smsObj);
smsEvent.setEventName("生日祝福短信事件");
this.applicationEventPublisher.publishEvent(smsEvent);
}
}
@SpringBootTest
class SpringEventDemoApplicationTests {
@Test
void contextLoads() {
}
@Test
public void test(){
ApplicationContext applicationContext=new AnnotationConfigApplicationContext("com.example.springeventdemo.*");
UserService userService = applicationContext.getBean("userService",UserService.class);
userService.registe();
userService.orderedOfUnPay();
userService.birthdayGreeting();
}
}
5. 总结
回到开头说的,学习想要掌握牢固就要带着问题去学习,那么到这里明白事件监听机制是解决什么问题,要用在什么样的场景下了吧?
当一个对象的状态发生变化时,所有依赖于它的对象需要被通知并作出相应的响应,只要符合这个特征,然后对具体的业务按照哪个是事件源、哪个是事件、哪个是监听器进行抽象封装就ok了。
Springboot扩展点系列实现方式、工作原理集合:
Springboot扩展点之ApplicationContextInitializer
Springboot扩展点之BeanDefinitionRegistryPostProcessor
Springboot扩展点之BeanFactoryPostProcessor
Springboot扩展点之BeanPostProcessor
Springboot扩展点之InstantiationAwareBeanPostProcessor
Springboot扩展点之SmartInstantiationAwareBeanPostProcessor
Springboot扩展点之ApplicationContextAwareProcessor
Springboot扩展点之@PostConstruct
Springboot扩展点之InitializingBean
Springboot扩展点之DisposableBean
Springboot扩展点之SmartInitializingSingleton
Springboot核心功能工作原理:
Springboot实现调度任务的工作原理
Springboot事件监听机制的工作原理
还没有评论,来说两句吧...