写点什么

如何基于 Spring 事件驱动模型实现业务解耦

发布于: 2021 年 02 月 01 日
如何基于Spring 事件驱动模型实现业务解耦

Spring 基于事件类 EventObject 和事件监听类 ApplicationListener 等实现了一套事件驱动模型,基于该模型可以实现服务之间的解耦,避免业务逻辑都堆积在一起,提升业务架构的可扩展性和可维护性。

一、Spring 事件驱动模型



所谓事件驱动,简单说实就是事件 A 的发生,关联驱动了其他事情的发生,比如一个用户注册成为某品牌微信会员后,商家可能会给用户发打折券、发短信通知等,在这个场景中,用户注册这一行为驱动了后续其他的动作。而用户注册之后的其他动作是可以通过观察者模式来进行解耦的。

 

Spring 的事件驱动模型由三部分组成:

 

事件:用户可自定义事件类和相关属性及行为来表述事件特征,Spring4.2 之后定义事件不需要再显式继承 ApplicationEvent 类,直接定义一个 bean 即可,Spring 会自动通过 PayloadApplicationEvent 来包装事件。

 

事件发布者:在 Spring 中可通过 ApplicationEventPublisher 把事件发布出去,这样事件内容就可以被监听者消费处理。

 

事件监听者:ApplicationListener,监听发布事件,处理事件发生之后的后续操作。

 

二、Spring 事件驱动实例


在 Spring4.2 之后,可以通过注解的方式来定义方法级别的事件监听行为,且自定义事件不需要再继承 ApplicationEvent,所以本文的示例不再使用之前的写法,当然代码也更加简洁一些。

 

1.定义事件


public class EventA { /** * 事件名称 */ private String eventName; public EventA(String eventName) { this.eventName = eventName; } public String getEventName() { return eventName; } public void setEventName(String eventName) { this.eventName = eventName; }}
public class EventB { /** * 事件名称 */ private String eventName; public EventB(String eventName) { this.eventName = eventName; } public String getEventName() { return eventName; } public void setEventName(String eventName) { this.eventName = eventName; }}
复制代码

2.定义事件发布者

@Component("eventPublisher")public class CommonEventPublisher {    private final ApplicationEventPublisher publisher;    public CommonEventPublisher(ApplicationEventPublisher publisher) {        this.publisher = publisher;    }    public void publishEvent() {        publisher.publishEvent(new EventA("事件A"));        publisher.publishEvent(new EventB("事件B"));    }}
复制代码

3.定义事件监听者

 

  • 通过 @EventListener 注解可定义方法级别的事件监听行为

  • @Async 表示异步处理,事件监听行为一般与事件发布者是解耦的,通过该注解异步处理监听内容。

@Servicepublic class CommonEventListener {    @EventListener    @Async    public void handleEventA(EventA eventA) {        System.out.println("正在处理 " + eventA.getEventName());    }
@EventListener @Async public void handleEventB(EventB eventB) { System.out.println("正在处理 " + eventB.getEventName()); }}
复制代码

4.测试用例

@RunWith(SpringRunner.class)@SpringBootTest(classes = {com.service.CommonEventListener.class,com.service.CommonEventPublisher.class})public class CommonEventListenerTest {    @Autowired    private CommonEventPublisher eventPublisher;    @Test    public void handleEvent() {        eventPublisher.publishEvent();    }}
复制代码

执行结果如下



Spring 事件模型的实现使用了观察者模式,提供了 Spring 容器中不同 bean 之间一种轻量级通信机制,合理的使用可以很好的解耦业务代码,并可以通过异步化避免服务之间不必要的同步调用,提升性能。


发布于: 2021 年 02 月 01 日阅读数: 60
用户头像

还未添加个人签名 2017.12.28 加入

公众号:技术进阶之路,专注技术开发能力的进阶写作分享,欢迎关注,共同进步!

评论

发布
暂无评论
如何基于Spring 事件驱动模型实现业务解耦