小白死磕之SpringBoot事件监听(event/listen)

124 阅读2分钟

背景

小白是从事医疗行业的相关业务开发设计工作

问题描述

业务场景:小白在实际业务开发中需要准对于 产品的 使用用户分不同角色进行发送不同的短信和站内信
    比如:
        1,给患者发送挂号成功的短信通知和站内信信通知
        2,给大夫发送通知短信和站内信息
        3,给药品管理者发送不要或者处方短信或者站内信信息
        
小白最初在业务代码中使用现成异步进行发送,可以实现功能。最终发现代码比较臃肿,耦合性太高,维护起来很麻烦。

有些业务中**还存在一些场景不需要在一次请求中同步完成。例如邮件发送、验证码发送等**,最后选择进行改造。

改造技术选型1:使用消息队列整改,最终论证放弃了,原因:MQ重量级的,架构复杂度高。

改造技术选型2:使用springboot轻量级的监听模式(观察者设计模式)Spring Event

解决方案示例代码

1.自定义事件 定义事件类,此事件类继承:[org.springframework.context.ApplicationEvent]

package xxx.monitor;

import org.springframework.context.ApplicationEvent;

/**
 * @Author: xb_lf
 * @Description: source 参数标识事件源  我的理解是作为事件的标识,当监听者监听事件事用来区分是何种事件,监听到事件触发是做事件类型区分,否则相同父类的事件被触发时会被执行多次
 * @Date: create in 2022/7/15 15:24
 * @Version:
 */
public class TestEvent extends ApplicationEvent {

    public String str;
    public TestEvent(Object source,String str) {
        super(source);
        this.str = str;
    }

    public String getStr(){
        return str;
    }
}

2.定义监听器 定义监听器类,此监听器类继承:[org.springframework.context.ApplicationListener]

package xxx.monitor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

/**
 * @Author: xb_lf
 * @Description:
 * @Date: create in 2022/7/15 15:26
 * @Version:
 */
@Service
@Slf4j
public class TestLister implements ApplicationListener<TestEvent> {
    @Override
    public void onApplicationEvent(TestEvent testEvent) {
        log.info("--->执行了");
        System.out.println(testEvent.getSource());
        System.out.println(testEvent.getStr());
    }
}
  1. 定义发布事件类 此事件发布类需要继承:[import org.springframework.context.ApplicationEventPublisherAware] ApplicationEventPublisherAware 此类是springboot的容器类,可以再此容器类中获取时间发布对象applicationEventPublisher
package xxx.web.service.impl;

import com.ldsight.ehealthy.operation.web.service.api.ITestOneService;
import com.ldsight.ehealthy.operation.web.service.monitor.TestEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

/**
 * @Author: xb_lf
 * @Description:
 * @Date: create in 2022/7/15 15:29
 * @Version:
 */
@Service
@Slf4j
public class ITestOneServiceImpl implements ITestOneService, ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void listenAndEventTest() {
        applicationEventPublisher.publishEvent(new TestEvent("AA","测试监听A"));
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}