Spring基于事件类EventObject和事件监听类ApplicationListener等实现了一套事件驱动模型,基于该模型可以实现服务之间的解耦,避免业务逻辑都堆积在一起,提升业务架构的可扩展性和可维护性。
一、Spring事件驱动模型
所谓事件驱动,简单说实就是事件A的发生,关联驱动了其他事情的发生,比如一个用户注册成为某品牌微信会员后,商家可能会给用户发打折券、发短信通知等,在这个场景中,用户注册这一行为驱动了后续其他的动作。而用户注册之后的其他动作是可以通过观察者模式来进行解耦的。
Spring的事件驱动模型由三部分组成:
事件:用户可自定义事件类和相关属性及行为来表述事件特征,Spring4.2之后定义事件不需要再显式继承ApplicationEvent类,直接定义一个bean即可,Spring会自动通过PayloadApplicationEvent来包装事件。
事件发布者:在Spring中可通过ApplicationEventPublisher把事件发布出去,这样事件内容就可以被监听者消费处理。
事件监听者:监听发布事件,处理事件发生之后的后续操作
二、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 表示异步处理,事件监听行为一般与事件发布者是解耦的,通过该注解异步处理监听内容。
@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之间一种轻量级通信机制,合理的使用可以很好的解耦业务代码,并可以通过异步化避免服务之间的同步调用,提升性能。
更多内容欢迎关注个人微信公众号,一起成长!