Spring Event
Spring Event 是基于观察者模式实现,介绍其之前,我们先介绍下JDK提供的观察者模型
观察者:Observer,
被观察:Observable
当被观察者改变时,其需要通知所有关联的观察者。Observable实现逻辑如下:
1、 Observable定义了一个数据结构:Vector<Observer>,记录关联的Observer。
2、 通知关联的观察者:调用方法notifyObservers(调用所有Observer的update方法)。
好了,下面我们介绍Spring基于观察者模式的Event机制
首先介绍Spring Event的关键的类
1、 ApplicationEvent 事件
2、 ApplicationListener 监听(Observer)
3、 ApplicationEventPublisher 发布(Observable)
整体逻辑如下:
ApplicationEventPublisher发布ApplicationEvent给关联的ApplicationListener。
根据观察者模式,我们可以推导出来:
ApplicationEventPublisher持有关联的ApplicationListener列表,调用ApplicationListener的方法(将ApplicationEvent作为入参传入过去),达到通知的效果。但问题来了,ApplicationEventPublisher如何知道这个ApplicationListener发给哪个ApplicationListener呢?
下面我们一步一步解析。
ApplicationListener(Observer)
ApplicationEventPublisher(Observable)
正在实现ApplicationEventPublisher.publishEvent这个方法的有两个类
有两个类AbstractApplicationContext和它的子类SimpleApplicationEventMulticaster
AbstractApplicationContext功能是存放所有关联的ApplicationListener。数据结构如下:
Map<ListenerCacheKey, ListenerRetriever> retrieverCache。
ListenerCacheKey构成:
1、ResolvableType eventType(对应的是ApplicationEvent)
2、Class<?> sourceType(对应的是EventObject)
ListenerRetriever构成:
1、 Set<ApplicationListener<?>> applicationListeners(监听)
答案很显然,ApplicationEventPublisher是通过ApplicationEvent(继承ApplicationEvent的Class类)类型来关联需要调用的ApplicationListener。
SimpleApplicationEventMulticaster的功能是:多线程调用所有关联的ApplicationListener的onApplicationEvent方法的。
实践:
创建Event
public class Event extends ApplicationEvent { private String message; public Event(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } }
创建监听:
1、实现ApplicationListener
@Component public class ImplementsListener implements ApplicationListener<Event> { @Override public void onApplicationEvent(Event event) { //TODO } }
2、加@EventListener注解
@Component public class AnnotationListener { @EventListener public void eventListener(Event event) { //TODO } }
事件发布:
@Component public class EventPublisher { @Autowired private ApplicationEventPublisher applicationEventPublisher; public void publish() { applicationEventPublisher.publishEvent(new Event(this, "it's demo")); } }
自定义事件广播:
@Component(APPLICATION_EVENT_MULTICASTER_BEAN_NAME) public class CustomApplicationEventMulticaster extends AbstractApplicationEventMulticaster { @Override public void multicastEvent(ApplicationEvent event) { //TODO custom invokeListener(listener, event); } @Override public void multicastEvent(ApplicationEvent event, ResolvableType eventType) { //TODO custom invokeListener(listener, event); } }