SpringBoot 源碼分析 - SpringApplication啟動流程四
- 初始化基本流程
- SimpleApplicationEventMulticaster的multicastEvent廣播事件
- resolveDefaultEventType獲取ResolvableType實例
- ResolvableType的forInstance創建ResolvableType實例
- 開始廣播
- AbstractApplicationEventMulticaster的getApplicationListeners獲取所有支持該事件的監聽器
- DefaultListenerRetriever
- getApplicationListeners直接獲取監聽器集合
- AbstractApplicationEventMulticaster的retrieveApplicationListeners
初始化基本流程
SimpleApplicationEventMulticaster的multicastEvent廣播事件
其實這個就是觀察者模式,發布訂閱模式,或者說事件驅動模式,如果看過netty就知道他里面的處理器的方法就是事件驅動模式,這里會先進行事件類型解析,解析成ResolvableType
類型。
org.springframework.context.event.SimpleApplicationEventMulticaster
@Overridepublic void multicastEvent(ApplicationEvent event) {multicastEvent(event, resolveDefaultEventType(event));}
resolveDefaultEventType獲取ResolvableType實例
private ResolvableType resolveDefaultEventType(ApplicationEvent event) {return ResolvableType.forInstance(event);}
ResolvableType的forInstance創建ResolvableType實例
如果是ResolvableTypeProvider
類型就會獲取類型實例返回,否則會創建一個ResolvableType
對象,將事件類型封裝進去。
public static ResolvableType forInstance(@Nullable Object instance) {if (instance instanceof ResolvableTypeProvider) {ResolvableType type = ((ResolvableTypeProvider) instance).getResolvableType();if (type != null) {return type;}}return (instance != null ? forClass(instance.getClass()) : NONE);}public static ResolvableType forClass(@Nullable Class<?> clazz) {return new ResolvableType(clazz);//創建一個,把clazz封裝進去}
開始廣播
獲取所有監聽器,如果沒有執行器就直接調用,有的話會開線程調用,最終都是 invokeListener
。
@Overridepublic void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));Executor executor = getTaskExecutor();for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {if (executor != null) {executor.execute(() -> invokeListener(listener, event));}else {invokeListener(listener, event);}}}
AbstractApplicationEventMulticaster的getApplicationListeners獲取所有支持該事件的監聽器
現在有個啟動事件,但是不一定所有監聽器都要支持該事件,如果不支持表示對此事件不關心,那就不需要通知給他了,所以這里就是為了找出支持該事件的監聽器集合,找出來之后還會給事件和監聽器集合做映射,放入緩存中。
protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {//獲取事件源,就是事件是誰觸發的Object source = event.getSource();Class<?> sourceType = (source != null ? source.getClass() : null);//事件源類型//封裝事件類型和事件源類型ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);// 定義一個檢索器CachedListenerRetriever newRetriever = null;// 從緩存中獲取CachedListenerRetriever existingRetriever = this.retrieverCache.get(cacheKey); //獲取監聽器檢索其if (existingRetriever == null) {// Caching a new ListenerRetriever if possibleif (this.beanClassLoader == null ||(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {newRetriever = new CachedListenerRetriever();existingRetriever = this.retrieverCache.putIfAbsent(cacheKey, newRetriever);if (existingRetriever != null) {newRetriever = null; // no need to populate it in retrieveApplicationListeners}}}if (existingRetriever != null) {//獲取支持該事件的監聽器集合,并放入retriever中Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();if (result != null) {return result;}}//不用緩存的情況,每次都取一遍return retrieveApplicationListeners(eventType, sourceType, newRetriever);}
DefaultListenerRetriever
這個其實就是存監聽器的,但是只是對某些事件支持的監聽器集合,可以是實例,也可以是 bean
的名字。
private class DefaultListenerRetriever {public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();public final Set<String> applicationListenerBeans = new LinkedHashSet<>();}
getApplicationListeners直接獲取監聽器集合
直接獲取就是將bean
名字的集合里的bean
都實例化,然后跟監聽器合并,去重,最后返回
public Collection<ApplicationListener<?>> getApplicationListeners() {List<ApplicationListener<?>> allListeners = new ArrayList<>(this.applicationListeners.size() + this.applicationListenerBeans.size());allListeners.addAll(this.applicationListeners);if (!this.applicationListenerBeans.isEmpty()) {BeanFactory beanFactory = getBeanFactory();for (String listenerBeanName : this.applicationListenerBeans) {try {ApplicationListener<?> listener =beanFactory.getBean(listenerBeanName, ApplicationListener.class);if (!allListeners.contains(listener)) {allListeners.add(listener);}}catch (NoSuchBeanDefinitionException ex) {// Singleton listener instance (without backing bean definition) disappeared -// probably in the middle of the destruction phase}}}AnnotationAwareOrderComparator.sort(allListeners);return allListeners;}
AbstractApplicationEventMulticaster的retrieveApplicationListeners
這個就是根據監聽器是否支持該事件,進行監聽器的篩選,最后把支持的監聽器集合返回。其實還會涉及到bean
名字的集合,支持該事件的會直接獲取,然后放進不同的集合里,最后都會講所有支持的監聽器全部返回。這里會把監聽器集合也放在ListenerRetriever
里,以便于做事件類型和監聽器集合的映射緩存。
private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {List<ApplicationListener<?>> allListeners = new ArrayList<>();Set<ApplicationListener<?>> filteredListeners = (retriever != null ? new LinkedHashSet<>() : null);Set<String> filteredListenerBeans = (retriever != null ? new LinkedHashSet<>() : null);Set<ApplicationListener<?>> listeners;Set<String> listenerBeans;synchronized (this.defaultRetriever) {//獲取SimpleApplicationEventMulticaster添加監聽器的時候就加入進去的監聽器集合listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);}// Add programmatically registered listeners, including ones coming// from ApplicationListenerDetector (singleton beans and inner beans).for (ApplicationListener<?> listener : listeners) {//遍歷所有的監聽器,看監聽器是否支持該事件if (supportsEvent(listener, eventType, sourceType)) {if (retriever != null) {filteredListeners.add(listener);//支持就添加進去}allListeners.add(listener);//也添加到allListeners里}}// Add listeners by bean name, potentially overlapping with programmatically// registered listeners above - but here potentially with additional metadata.if (!listenerBeans.isEmpty()) {//如果有監聽的bean的話,也要加進去ConfigurableBeanFactory beanFactory = getBeanFactory();for (String listenerBeanName : listenerBeans) {try {if (supportsEvent(beanFactory, listenerBeanName, eventType)) {//支持該事件的直接獲取ApplicationListener<?> listener =beanFactory.getBean(listenerBeanName, ApplicationListener.class);if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {if (retriever != null) {if (beanFactory.isSingleton(listenerBeanName)) {filteredListeners.add(listener);}else {filteredListenerBeans.add(listenerBeanName);}}allListeners.add(listener);}}else {//不支持就刪除// Remove non-matching listeners that originally came from// ApplicationListenerDetector, possibly ruled out by additional// BeanDefinition metadata (e.g. factory method generics) above.Object listener = beanFactory.getSingleton(listenerBeanName);if (retriever != null) {filteredListeners.remove(listener);}allListeners.remove(listener);}}catch (NoSuchBeanDefinitionException ex) {// Singleton listener instance (without backing bean definition) disappeared -// probably in the middle of the destruction phase}}}AnnotationAwareOrderComparator.sort(allListeners);if (retriever != null) {if (filteredListenerBeans.isEmpty()) {retriever.applicationListeners = new LinkedHashSet<>(allListeners);retriever.applicationListenerBeans = filteredListenerBeans;}else {retriever.applicationListeners = filteredListeners;retriever.applicationListenerBeans = filteredListenerBeans;}}return allListeners;}