概念
springboot在启动流程中会发布一些事件通知依赖组件进行主动更新。
原理是springboot使用到的一种设计模式: 观察者模式。优点是解耦合启动流程,增加了spring的扩展性。
实现原理
被观察者会维护一个事件发布器,事件发布器会注册持有监听者(观察者)的引用。
当被观察者发生状态改变,事件发布器会广播给所有对该事件感兴趣的监听者,之后监听者会执行对应的事件触发方法。
uml类图
事件发布流程
源码剖析
事件发布触发
/** springApplication.class 事件发布 */ public ConfigurableApplicationContext run(String... args) { ... // 扫描META-INF/spring-factories 中的org.springframework.boot.SpringApplicationRunListener,构造事件发布器 SpringApplicationRunListeners listeners = this.getRunListeners(args); // ★ 给关注ApplicationStartingEvent事件的listenter发布消息 listeners.starting(); ... } /** EventPublishingRunListener.class 事件发布器 */ // 构造方法(实现的观察者模式:由被观察者维护监听者并广播消息) public EventPublishingRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; // ★ 实例化一个广播器 this.initialMulticaster = new SimpleApplicationEventMulticaster(); Iterator var3 = application.getListeners().iterator(); // ★ 把springapplication类的监听器都注册到广播器中 while(var3.hasNext()) { ApplicationListener<?> listener = (ApplicationListener)var3.next(); this.initialMulticaster.addApplicationListener(listener); } } // 发布ApplicationStartingEvent事件 public void starting() { // 广播事件 this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args)); }
广播事件
/** SimpleApplicationEventMulticaster.class 广播器 */ // 广播事件 public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event); // 多线程执行监听器更新 Executor executor = this.getTaskExecutor(); // 1.获取需要更新的监听器 Iterator var5 = this.getApplicationListeners(event, type).iterator(); // 2.执行监听器的更新 while(var5.hasNext()) { ApplicationListener<?> listener = (ApplicationListener)var5.next(); if (executor != null) { executor.execute(() -> { this.invokeListener(listener, event); }); } else { // 最底层其实就是执行listener实现的onApplicationEvent(event)方法 this.invokeListener(listener, event); } } } // 1.获取监听器 protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event, ResolvableType eventType) { // sprinApplication对象和类 Object source = event.getSource(); Class<?> sourceType = source != null ? source.getClass() : null; // cacheKey记录当前事件和事件类型 AbstractApplicationEventMulticaster.ListenerCacheKey cacheKey = new AbstractApplicationEventMulticaster.ListenerCacheKey(eventType, sourceType); // retriever记录对应事件需要更新的监听器 AbstractApplicationEventMulticaster.ListenerRetriever retriever = (AbstractApplicationEventMulticaster.ListenerRetriever)this.retrieverCache.get(cacheKey); if (retriever != null) { return retriever.getApplicationListeners(); } else if (this.beanClassLoader == null || ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) && (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader))) { synchronized(this.retrievalMutex) { retriever = (AbstractApplicationEventMulticaster.ListenerRetriever)this.retrieverCache.get(cacheKey); if (retriever != null) { return retriever.getApplicationListeners(); } else { retriever = new AbstractApplicationEventMulticaster.ListenerRetriever(true); // 1.1 筛选对事件感兴趣的监听者 Collection<ApplicationListener<?>> listeners = this.retrieveApplicationListeners(eventType, sourceType, retriever); this.retrieverCache.put(cacheKey, retriever); return listeners; } } } else { return this.retrieveApplicationListeners(eventType, sourceType, (AbstractApplicationEventMulticaster.ListenerRetriever)null); } } // 1.1 筛选监听者 private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable AbstractApplicationEventMulticaster.ListenerRetriever retriever) { List<ApplicationListener<?>> allListeners = new ArrayList(); LinkedHashSet listeners; LinkedHashSet listenerBeans; // 监听器数组 synchronized(this.retrievalMutex) { listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners); listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans); } Iterator var7 = listeners.iterator(); // 1.1.1 感兴趣的放入retriever数组中 while(var7.hasNext()) { ApplicationListener<?> listener = (ApplicationListener)var7.next(); if (this.supportsEvent(listener, eventType, sourceType)) { if (retriever != null) { retriever.applicationListeners.add(listener); } allListeners.add(listener); } } // 我运行的时候没有走到,多加了单例相关的判断 if (!listenerBeans.isEmpty()) { /* ... */ } // 排序,更新retriever的监听者 AnnotationAwareOrderComparator.sort(allListeners); if (retriever != null && retriever.applicationListenerBeans.isEmpty()) { retriever.applicationListeners.clear(); retriever.applicationListeners.addAll(allListeners); } return allListeners; } // 1.1.1 监听器是否对事件感兴趣 protected boolean supportsEvent(ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) { // 转成通用监听类型 GenericApplicationListener smartListener = listener instanceof GenericApplicationListener ? (GenericApplicationListener)listener : new GenericApplicationListenerAdapter(listener); // 看监听器自己实现的supportsEventType和supportsSourceType方法是否对该事件感兴趣 return ((GenericApplicationListener)smartListener).supportsEventType(eventType) && ((GenericApplicationListener)smartListener).supportsSourceType(sourceType); }
标签:listener,springboot,eventType,剖析,源码,事件,监听器,null,retriever From: https://www.cnblogs.com/Duikerdd/p/16841343.html