本節則重點關注的是 Spring 的事件監聽機制,主要是第 8 步:多播器註冊;第 10 步:事件註冊。java
public void refresh() throws BeansException, IllegalStateException { // 8. 註冊多播器,事件監聽器的管理者 initApplicationEventMulticaster(); // 9. 專門留給子類初始化其它 bean 用,這是一個空的方法 onRefresh(); // 10. 註冊監聽器 registerListeners(); }
事件定義以下,實現了 JDK 的規範 EventListenerspring
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { // 監聽 event 事件 void onApplicationEvent(E event); }
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class MyApplicationListener implements ApplicationListener<ApplicationEvent> { @Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("接收的事件:" + event); } }
運行後結果以下:app
接收的事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@16eabae: startup date [Sun Jul 29 12:41:42 CST 2018]; root of context hierarchy]
ApplicationContext 中 refresh() 第 8 步 initApplicationEventMulticaster() 進行多播器的初始化工做ide
源代碼【AbstractApplicationContext】this
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); } }
ApplicationContext 中 refresh() 第 10 步 registerListeners() 進行事件監聽者的註冊工做。code
源代碼【AbstractApplicationContext】事件
protected void registerListeners() { // 1. 註冊靜態指定的偵聽器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 2. 註冊 ApplicationListener String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 3. Publish early application events Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
源代碼【AbstractApplicationContext】get
public void publishEvent(ApplicationEvent event) { publishEvent(event, null); } public void publishEvent(Object event) { publishEvent(event, null); } protected void publishEvent(Object event, ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); // 1. 若是 event 不是 ApplicationEvent,則須要進行封裝成 PayloadApplicationEvent ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { eventType = ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, event.getClass()); } } // 2. 發佈事件 event,若是多播器懶加載,尚未初始化則將該事件先放到 earlyApplicationEvents 容器中 // 等待多播器建立好了再發布事件 ??? if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // 3. 父容器中也須要發佈該事件 event if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
天天用心記錄一點點。內容也許不重要,但習慣很重要!it