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.定义事件监听者
@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 之间一种轻量级通信机制,合理的使用可以很好的解耦业务代码,并可以通过异步化避免服务之间不必要的同步调用,提升性能。
评论