Springboot事件监听机制:实战应用

目录

前言

1. 事件监听机制的定义

2. 事件监听机制的应用场景

3. 事件监听机制的好处

4. springboot事件监听机制的实现

5. 总结


前言

        事件监听机制是一套很有用的机制,其原理就是观察者模式,而观察者模式又被称为发布-订阅模式,有人说23种设计模式平时很少用上,总是看了忘,我只能说你太不走心了。我的经验就是一定要带着问题去学习新东西,设计模式不仅是一套理论,更是长期的工程实践总结出来经验、解决方案。想要掌握好,必须要弄清每一个设计模式的本质是为了解决什么问题。

1. 事件监听机制的定义

        事件监听机制的本质是一套流程,这套流程描述的是某个位置发生了一些事,发生的这些事又触发了另外一些事。如果使用面向对象的思想对这套流程进行抽象,会抽象出来几个非常关键的类,分别是事件源、事件、监听器。

        事件源:就是所谓的某个位置

        事件:就是某个位置发生的一些事;                

        监听器:某个位置发生一些事后,被监听器知道了,又触发监听器的一些行为;

        把这些片断信息连起来,就是在事件源产生事件,被监听器捕获,然后又触发了其他行为。

        如果还是觉得抽象,举个例子:明朝的锦衣卫相信大家都非常熟悉,飞鱼服绣春刀的,帅得狠,当然这不是重点,重点是朱老总打下江山,总害怕乱臣贼子干坏事,于是乎创立了锦衣卫制度。那些老朱觉得危险的王侯、勋臣、大将军什么的,各家都派些锦衣卫盯着,每天吃喝了啥、写了啥文章、说了啥话、平时和那些人交往、收没收礼、有没有贪污、有没有不法行为,事无巨细都报到东厂来。老朱的这一套操作下来,就是一套事件监听机制。事件源就是那些被监视的对象,事件就是大臣们有没有不法行为,监听器就是大臣们家的不起眼小妾、仆人、丫鬟(没有飞鱼服、绣春刀的也有可能是锦衣卫),一旦这些大臣有啥不法事情马上会被报告到东厂,然后老朱就知道了,该处理处理。这就是事件监听机制,或者叫观察者模式、监听者模式,叫什么无所谓,本质是一样的。

2. 事件监听机制的应用场景

      在程序设计里有哪些场景会用到呢?下面举一些例子: 用户注册成功了,得发个提示短信吧,用户下单成功迟迟不付款得发个提示短信吧,用户生日了得发送个祝福短信吧,这些都是比较简单的场景,简单抽象一下,用户的很多业务行为都会有要发短信的需求,如果每个业务行为都各自发短信,那么首先业务行为与发短信就耦合了,不利于后续扩展,其次具有相同特征的行为一直重复。使用事件监听机制改造一下,把各个业务行为内的短信内容封装成一个事件,业务行为触发的时候发布这个事件,再把具体发短信的行为封装到监听器里,监听到事件源发布的事件后,触发具体的发短信的行为。

3. 事件监听机制的好处

  1. 业务与业务之间解耦,符合依赖倒置原则;
  2. 代码复用,更容易维护,也提高了执行效率;

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事件监听机制的工作原理

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凡夫贩夫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值