public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { /** * Handle an application event. * @param event the event to respond to */ void onApplicationEvent(E event); }
SimpleApplicationEventMulticaster#multicastEvent
執行調用所有實現了ApplicationListener
接口的Bean.
/* *廣播所有注冊監聽的事件 *設置個Excutor可以異步執行 */ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { private Executor taskExecutor;//可以異步執行listener ...... @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public void multicastEvent(final ApplicationEvent event) { //遍歷執行listener,getApplicationListeners調用AbstractApplicationEventMulticaster父類方法 for (final ApplicationListener listener : getApplicationListeners(event)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(new Runnable() { @Override public void run() { listener.onApplicationEvent(event); } }); } else { listener.onApplicationEvent(event); } } } }
父類AbstractApplicationEventMulticaster#getApplicationListeners()
部分源碼:
/* *抽象AbstractApplicationEventMulticaster 事件廣播者 */ public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware { ..... //實現此BeanFactoryAware接口,初始化時,將會將beanFactory注入到該實例中。便於后續獲取bean private BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) { this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader(); } } ...... /* *獲取容器監聽 */ protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event) { Class<? extends ApplicationEvent> eventType = event.getClass(); Object source = event.getSource(); Class<?> sourceType = (source != null ? source.getClass() : null); ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType); ListenerRetriever retriever = this.retrieverCache.get(cacheKey); if (retriever != null) { return retriever.getApplicationListeners(); } else { retriever = new ListenerRetriever(true); LinkedList<ApplicationListener<?>> allListeners = new LinkedList<ApplicationListener<?>>(); Set<ApplicationListener<?>> listeners; Set<String> listenerBeans; synchronized (this.defaultRetriever) { listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners); listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans); } for (ApplicationListener<?> listener : listeners) { if (supportsEvent(listener, eventType, sourceType)) { retriever.applicationListeners.add(listener); allListeners.add(listener); } } if (!listenerBeans.isEmpty()) { BeanFactory beanFactory = getBeanFactory(); for (String listenerBeanName : listenerBeans) { try { Class<?> listenerType = beanFactory.getType(listenerBeanName); if (listenerType == null || supportsEvent(listenerType, event)) { ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class); if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) { retriever.applicationListenerBeans.add(listenerBeanName); allListeners.add(listener); } } } catch (NoSuchBeanDefinitionException ex) { // Singleton listener instance (without backing bean definition) disappeared - // probably in the middle of the destruction phase } } }
//對監聽排序 OrderComparator.sort(allListeners); if (this.beanClassLoader == null || (ClassUtils.isCacheSafe(eventType, this.beanClassLoader) && (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) { this.retrieverCache.put(cacheKey, retriever); } return allListeners; } } .... }
AbstractApplicationContext#publishEvent()
調用發布事件源碼
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean{ ...... public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster"; ...... /** * 初始化事件廣播器,如果未配置,默認使用SimpleApplicationEventMulticaster *這個何時執行?稍后將會貼出代碼 */ 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); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } } ...... //獲取容器事件廣播器 ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException { if (this.applicationEventMulticaster == null) { throw new IllegalStateException("ApplicationEventMulticaster not initialized - " + "call 'refresh' before multicasting events via the context: " + this); } return this.applicationEventMulticaster; } ...... @Override public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } //獲取到事件廣播器,發布事件 getApplicationEventMulticaster().multicastEvent(event); //如果存在父容器,父容器也將發布事件 if (this.parent != null) { this.parent.publishEvent(event); } } ...... }
AbstractApplicationContext#finishRefresh()
源碼
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean{ ...... protected void finishRefresh() { // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. 發布事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); } ...... }
AbstractApplicationContext#refresh()
源碼
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean{ ..... @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context.初始化事件廣播器,如果未配置,默認使用SimpleApplicationEventMulticaster initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.完成refresh finishRefresh(); } catch (BeansException ex) { logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex); // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } } ..... }
spring容器啟動將會執行到AbstractApplicationContext#refresh()
。由此可以看到spring事件的流程,在關注的地方都加了注釋。我們看代碼不要挨着看,觀其大意。看自己需要的就行。
下面寫了一個demo看看,如何實現事件的異步。
/** * @Auther: lanwei * @Date: 2018/11/1 23:38 * @Description: */ public class ApplicationListenerAsynTest { public static void main(String[] args) { final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.addApplicationListener(new ApplicationListener<ApplicationEvent>() { @Override public void onApplicationEvent(ApplicationEvent event) { println(event.getSource().toString()); } }); context.register(MyConfiguration.class); context.refresh(); context.close(); } @Configuration public static class MyConfiguration { @Bean public SimpleApplicationEventMulticaster applicationEventMulticaster() { SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster(); multicaster.setTaskExecutor(new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10))); return multicaster; } } private static void println(String message) { System.out.printf("[線程 : %s] %s\n", Thread.currentThread().getName(), // 當前線程名稱 message); } }