Spring Event 是基於觀察者模式實現,介紹其以前,咱們先介紹下JDK提供的觀察者模型數據結構
觀察者:Observer,多線程
被觀察:Observableapp
當被觀察者改變時,其須要通知全部關聯的觀察者。Observable實現邏輯以下:ide
一、 Observable定義了一個數據結構:Vector<Observer>,記錄關聯的Observer。
二、 通知關聯的觀察者:調用方法notifyObservers(調用全部Observer的update方法)。
好了,下面咱們介紹Spring基於觀察者模式的Event機制this
首先介紹Spring Event的關鍵的類spa
一、 ApplicationEvent 事件線程
二、 ApplicationListener 監聽(Observer)code
三、 ApplicationEventPublisher 發佈(Observable)server
總體邏輯以下:blog
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構成:
一、ResolvableType eventType(對應的是ApplicationEvent)
二、Class<?> sourceType(對應的是EventObject)
ListenerRetriever構成:
一、 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; } }
建立監聽:
一、實現ApplicationListener
@Component public class ImplementsListener implements ApplicationListener<Event> { @Override public void onApplicationEvent(Event event) { //TODO } }
二、加@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); } }