1. 背景
Spring的事件通知机制是一项很有用的功能,使用事件机制我们可以将相互耦合的代码解耦,从而方便功能的修改与添加。本文我来学习并分析一下Spring中事件的原理。
举个例子,假设有一个添加评论的方法,在评论添加成功之后需要进行修改redis缓存、给用户添加积分等等操作。当然可以在添加评论的代码后面假设这些操作,但是这样的代码违反了设计模式的多项原则:单一职责原则、迪米特法则、开闭原则。一句话说就是耦合性太大了,比如将来评论添加成功之后还需要有另外一个操作,这时候我们就需要去修改我们的添加评论代码了。
在以前的代码中,我使用观察者模式来解决这个问题。不过Spring中已经存在了一个升级版观察者模式的机制,这就是监听者模式。通过该机制我们就可以发送接收任意的事件并处理。
通过一个简单的demo来看看Spring事件通知的使用:
// 定义一个事件
public class EventDemo extends ApplicationEvent {
private String message;
public EventDemo(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
// 定义一个事件监听者
@Component
public class EventDemoListener implements ApplicationListener<EventDemo> {
@Override
public void onApplicationEvent(EventDemo event) {
System.out.println("receiver " + event.getMessage());
}
}
// 事件发布
@Component
public class EventDemoPublish {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void publish(String message) {
EventDemo demo = new EventDemo(this, message);
applicationEventPublisher.publishEvent(demo);
}
}
调用EventDemoPublish.publish方法来发布消息,EventDemoListener监听器接收到消息后对消息进行处理,打印出消息的内容:
receiver hello
2. Spring事件通知原理
首先我们跟踪publishEvent方法,这个方法在AbstractApplicationContext类中。
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
// 如果event是ApplicationEvent对象
applicationEvent = (ApplicationEvent