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