springBoot启动之事件监听机制源码解析

1. Java的事件监听机制

在进行正式的分析之前,先介绍一下Java的事件监听机制。参考05–SpringBoot启动之事件监听机制

Java事件监听机制包含3要素:被监听的事件(evevt)、事件源、事件监听器(listener)。

被监听的事件(evevt)继承–>java.util.EventObject

事件监听器(listener)实现–>java.util.EventListener接口

事件源 中必须包含事件监听器注册、发布、取消等功能,其余功能看具体情况而定。

1.1 自定义事件

package com.swj.myObserver;import java.util.EventObject;public class MethodMonitorEvent extends EventObject {public long timestamp;/*** Constructs a prototypical Event.** @param source The object on which the Event initially occurred.* @throws IllegalArgumentException if source is null.*/public MethodMonitorEvent(Object source) {super(source);}
}

1.2 自定义监听器

package com.swj.myObserver;import java.util.EventListener;public class MethodMonitorEventListener implements EventListener {public void onMethodBegin(MethodMonitorEvent event) {// 记录方法开始执行时的时间System.out.println("==记录方法耗时开始");event.timestamp = System.currentTimeMillis();}public void onMethodEnd(MethodMonitorEvent event) {// 计算方法耗时long duration = System.currentTimeMillis() - event.timestamp;System.out.println("==记录方法耗时结束");System.out.println("==耗时:" + duration);}
}

1.3 自定义事件源

package com.swj.myObserver;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;public class MethodMonitorEventPublisher {private List<MethodMonitorEventListener> listeners = new ArrayList<MethodMonitorEventListener>();public void methodMonitor() throws InterruptedException {MethodMonitorEvent eventObject = new MethodMonitorEvent(this);publishEvent("begin", eventObject);// 模拟方法执行:休眠5秒钟TimeUnit.SECONDS.sleep(5);publishEvent("end", eventObject);}private void publishEvent(String status, MethodMonitorEvent event) {List<MethodMonitorEventListener> copyListeners = new ArrayList<MethodMonitorEventListener>(listeners);for (MethodMonitorEventListener listener : copyListeners) {if ("begin".equals(status)) {listener.onMethodBegin(event);} else {listener.onMethodEnd(event);}}}/*** 监听器注册* @param listener*/public void addEventListener(MethodMonitorEventListener listener) {listeners.add(listener);}/*** 监听器销毁* @param listener*/public void deleteEventListener(MethodMonitorEventListener listener){listeners.remove(listener);}public static void main(String[] args) throws InterruptedException {MethodMonitorEventPublisher publisher = new MethodMonitorEventPublisher();publisher.addEventListener(new MethodMonitorEventListener());publisher.methodMonitor();}}

2. springBoot启动过程中的事件监听机制

2.1 springBoot中事件、监听器、数据源、以及涉及到的相关java类关系逻辑梳理

在进行正式的开始分析之前,先把springBoot中事件、监听器、数据源、以及涉及到的相关java类关系逻辑梳理一下,免得读者看着混乱,因为我之前学习得时候看看看着就看懵逼了。

2.1.1 springBoot事件说明

先来一张UML图


在看下SpringApplicationEvent有哪些子类,如图

所有关于springBoot event的全部UML图读者可以自行脑部一下,这里就不给出来了。

2.1.2 springBoot监听器

springBoot中有2个监听器的interface:ApplicationListenerSpringApplicationRunListener,读者可以这么理解,强调只能这么去理解,从继承、实现的角度上来看这两个监听器并没这种关系:SpringApplicationRunListener是对ApplicationListener的一层包裹,先是执行SpringApplicationRunListener中的方法,但这个方法只是一个空壳子,真正的逻辑是在ApplicationListener中实现的。但是要知道这两个其实都是接口,真正的实现都是在他们的实现类中SpringApplicationRunListener的实现类只有一个:EventPublishingRunListener

UML图给出


关于ApplicationListener的实现类,我们只关心一下这些,其他的暂时不在考虑范围之内。

org.springframework.boot.ClearCachesApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.context.FileEncodingApplicationListener
org.springframework.boot.context.config.AnsiOutputApplicationListener
org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
org.springframework.boot.logging.ClasspathLoggingApplicationListener
org.springframework.boot.logging.LoggingApplicationListener
org.springframework.boot.autoconfigure.BackgroundPreinitializer

2.1.3 springBoot事件源

springboot的事件源是SpringApplicationRunListeners类,主要作用就是存储监听器对象集合并发布各种监听事件。

  • SpringApplicationRunListeners中包含了private final List<SpringApplicationRunListener> listeners集合

  • 真正负责事件发布的是SpringApplicationRunListener

  • SpringApplicationRunListener中又维护了SimpleApplicationEventMulticaster对象,并通过该对象将事件广播给各个监听器

大概总结一下上述这些类的关系,以监听器的启动为例:

  1. 启动监听器,执行SpringApplicationRunListeners.starting()方法
  2. 本质上是调用SpringApplicationRunListener.starting()方法—>实现类EventPublishingRunListener.starting()方法
  3. SimpleApplicationEventMulticaster.multicastEvent方法
  4. ApplicationListener.onApplicationEvent方法—>实现类监听器(如LoggingApplicationListener,ConfigFileApplicationListener)的onApplicationEvent方法

2.2 SpringBoot中的事件监听机制

2.2.1 SpringBoot启动过程中监听器注册

在springBoot启动的run方法中与这么一行代码:

SpringApplicationRunListeners listeners = getRunListeners(args);

在springboot启动源码分析 3.2小节已经对这行代码进行了详细的源码解析,有兴趣的读者可以去看看,说过这么一句话:

EventPublishingRunListener类实例化的时候使用的是自身的构造方法,如下:

public EventPublishingRunListener(SpringApplication application, String[] args) {this.application = application;this.args = args;this.initialMulticaster = new SimpleApplicationEventMulticaster();for (ApplicationListener<?> listener : application.getListeners()) {this.initialMulticaster.addApplicationListener(listener);}
}

this.initialMulticaster.addApplicationListener(listener)这行代码,作用就是给AbstractApplicationEventMulticaster类中defaultRetriever变量中的applicationListeners添加ApplicationListener的子实现类,也就是我们说的真正的监听器。

现在可以给SpringApplicationRunListeners listeners = getRunListeners(args)这行代码一个明确的解释,作用如下:

获取classpath下META-INF/spring.factories中SpringApplicationRunListener.class全类名对应属性值的实例集合,也就是springBoot实际监控事件的监听器,并注册这些监听器

2.2.2 springBoot监听器的发布(启动)

在 2.2.1小节已经介绍了SpringBoot启动过程中监听器注册,现在介绍监听器的发布(启动)。

在springBoot启动的run方法中与这么一行代码:

listeners.starting();

这行代码就是用来启动监听器的,下面对它进行源码解析,先看实现:

public void starting() {for (SpringApplicationRunListener listener : this.listeners) {listener.starting();}
}//this.listeners中listeners定义
private final List<SpringApplicationRunListener> listeners;

其实在springBoot启动执行到listeners.starting()的时候,listeners里面就只有一个EventPublishingRunListener,不理解的读者可以参看springboot启动源码分析3.2小节,点进去看实现

private final SimpleApplicationEventMulticaster initialMulticaster;public void starting() {this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args));
}

SimpleApplicationEventMulticaster继承AbstractApplicationEventMulticaster

new ApplicationStartedEvent(this.application, this.args)没什么好讲的,就是初始化一个ApplicationStartedEvent事件,关于在于multicastEvent方法,继续跟踪源码:

@Override
public void multicastEvent(ApplicationEvent event) {multicastEvent(event, resolveDefaultEventType(event));
}

resolveDefaultEventType(event)就不分析了,重点不再这里,关键在于重载的multicastEvent方法

@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));//getApplicationListeners(event, type)-->通过给定的事件类型,返回监听器集合//此处获取到的监听器有LoggingApplicationListener,//DelegatingApplicationListener,//LiquibaseServiceLocatorApplicationListener等监听器,//以LoggingApplicationListener为例继续debug跟踪,至于符合获取对应的监听器,放在下面分析for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {//如果上下文中有线程池则使用线程池调用Executor executor = getTaskExecutor();if (executor != null) {executor.execute(new Runnable() {@Overridepublic void run() {invokeListener(listener, event);}});}else {invokeListener(listener, event);}}
}

invokeListener(listener, event)实现如下:


protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {ErrorHandler errorHandler = getErrorHandler();if (errorHandler != null) {try {doInvokeListener(listener, event);}catch (Throwable err) {errorHandler.handleError(err);}}else {doInvokeListener(listener, event);}
}

doInvokeListener(listener, event)实现

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {try {listener.onApplicationEvent(event);}catch (ClassCastException ex) {String msg = ex.getMessage();if (msg == null || msg.startsWith(event.getClass().getName())) {Log logger = LogFactory.getLog(getClass());if (logger.isDebugEnabled()) {logger.debug("Non-matching event type for listener: " + listener, ex);}}else {throw ex;}}
}

前面说了以LoggingApplicationListener为例,到这一步就是执行监听器自身定义的方法了,代码如下:

//实例化loggingSystem并将将日志记录系统重置为限制输出。
private void onApplicationStartingEvent(ApplicationStartingEvent event) {this.loggingSystem =  LoggingSystem.get(event.getSpringApplication().getClassLoader());this.loggingSystem.beforeInitialize();
}

到这一步监听器的发布(启动)基本就分析结束了,关于监听器自身的onApplicationStartingEvent方法这里不予介绍。

2.2.1 getApplicationListeners(event, type)方法解析

前面分析有一处没有解释的地方,就是getApplicationListeners(event, type)方法

for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {......
}

下面开始分析,方法实现如下:

protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {// 获取事件的source,其实就是SpringApplication对象Object source = event.getSource();Class<?> sourceType = (source != null ? source.getClass() : null);//初始化ListenerCacheKey对象ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);//查看retrieverCache中是否已经存在和某个事件的对应的ListenerRetriever对象retrieverListenerRetriever retriever = this.retrieverCache.get(cacheKey);//如果retriever不为null,直接取对应的监听器集合if (retriever != null) {return retriever.getApplicationListeners();}if (this.beanClassLoader == null ||(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {// Fully synchronized building and caching of a ListenerRetrieversynchronized (this.retrievalMutex) {retriever = this.retrieverCache.get(cacheKey);if (retriever != null) {return retriever.getApplicationListeners();}retriever = new ListenerRetriever(true);Collection<ApplicationListener<?>> listeners =retrieveApplicationListeners(eventType, sourceType, retriever);this.retrieverCache.put(cacheKey, retriever);return listeners;}}else {// No ListenerRetriever caching -> no synchronization necessaryreturn retrieveApplicationListeners(eventType, sourceType, null);}}

可以看到这个方法的核心就在于retrieveApplicationListeners方法,继续跟踪源码

private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {LinkedList<ApplicationListener<?>> allListeners = new LinkedList<ApplicationListener<?>>();Set<ApplicationListener<?>> listeners;Set<String> listenerBeans;synchronized (this.retrievalMutex) {// this.defaultRetriever.applicationListeners中包含10和监听器对象,在3.2.1监听器注册的// 时候放入的,有疑问可以翻回去看listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);}//遍历10个监听器,依次调用supportsEvent方法for (ApplicationListener<?> listener : listeners) {if (supportsEvent(listener, eventType, sourceType)) {if (retriever != null) {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, eventType)) {ApplicationListener<?> listener =beanFactory.getBean(listenerBeanName, ApplicationListener.class);if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {if (retriever != null) {retriever.applicationListenerBeans.add(listenerBeanName);}allListeners.add(listener);}}}catch (NoSuchBeanDefinitionException ex) {}}}AnnotationAwareOrderComparator.sort(allListeners);return allListeners;
}
2.2.1.1 supportsEvent方法解析

看下supportsEvent(listener, eventType, sourceType)这个方法的实现

protected boolean supportsEvent(ApplicationListener<?> listener, ResolvableType        eventType, Class<?> sourceType) {GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));return (smartListener.supportsEventType(eventType) &&  smartListener.supportsSourceType(sourceType));
}

根据传入的监听器类型做判断:

  • 若监听器是GenericApplicationListener的子类,则直接调用监听器的supportsEventType,supportsSourceType方法
  • 若监听器不是GenericApplicationListener的子类,则初始化一个GenericApplicationListenerAdapter对象,调用GenericApplicationListenerAdapter的supportsEventType,supportsSourceType方法

先看第一种逻辑:

若监听器是GenericApplicationListener的子类,则直接调用监听器的supportsEventType方法(supportsSourceType方法的实现和supportsEventType方法是类似的,所以不解析supportsSourceType,读者自行看下就明白了)

还是以LoggingApplicationListener为例,supportsEventType方法源码如下:

@Override
public boolean supportsEventType(ResolvableType resolvableType) {return isAssignableFrom(resolvableType.getRawClass(), EVENT_TYPES);
}//EVENT_TYPES定义
private static Class<?>[] EVENT_TYPES = { ApplicationStartingEvent.class,ApplicationEnvironmentPreparedEvent.class,       ApplicationPreparedEvent.class,ContextClosedEvent.class, ApplicationFailedEvent.class
};private boolean isAssignableFrom(Class<?> type, Class<?>... supportedTypes) {if (type != null) {for (Class<?> supportedType : supportedTypes) {if (supportedType.isAssignableFrom(type)) {return true;}}}return false;
}

可以看到LoggingApplicationListener匹配的事件类型有5种:

  • ApplicationStartingEvent
  • ApplicationEnvironmentPreparedEvent
  • ApplicationPreparedEvent
  • ContextClosedEvent
  • ApplicationFailedEvent

而我们前面传入的是ApplicationStartingEvent事件类型,所以LoggingApplicationListener是能够和ApplicationStartingEvent匹配的,同样的,其他实现GenericApplicationListener的监听器接口也是需要去分析自己的supportsEventType方法,这里就在赘述了,读者可自行选择另外的监听器进行分析。

再看另外一种逻辑:

若监听器不是GenericApplicationListener的子类,则初始化一个GenericApplicationListenerAdapter对象,调用GenericApplicationListenerAdapter的supportsSourceType方法

先看源码:

public boolean supportsEventType(ResolvableType eventType) {//判定delegate是不是SmartApplicationListener的子类if (this.delegate instanceof SmartApplicationListener) {//获取监听器的class对象Class<? extends ApplicationEvent> eventClass = (Class<? extends                           ApplicationEvent>) eventType.resolve();return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));}else {return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));}}//delegate定义
private final ApplicationListener<ApplicationEvent> delegate;
//declaredEventType定义
private final ResolvableType declaredEventType;

delegate其实就是我们传入的监听器对象,注意GenericApplicationListenerAdapter的构造方法:

public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {Assert.notNull(delegate, "Delegate listener must not be null");this.delegate = (ApplicationListener<ApplicationEvent>) delegate;this.declaredEventType = resolveDeclaredEventType(this.delegate);
}

接着看GenericApplicationListenerAdaptersupportsEventType方法的逻辑,就是根据delegate是否是SmartApplicationListener的子类分成两种处理

  • 若是SmartApplicationListener的子类

    核心就在于 ((SmartApplicationListener) this.delegate).supportsEventType(eventClass))SmartApplicationListener是一个interface,所以调用的还是监听器自身的supportsEventType方法。

    就以ConfigFileApplicationListener为例,看下它的supportsEventType方法:

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)|| ApplicationPreparedEvent.class.isAssignableFrom(eventType);
    }
    

    可以看到ConfigFileApplicationListener匹配的事件类型有2种:

    • ApplicationEnvironmentPreparedEvent
    • ApplicationPreparedEvent

    但是我们再执行监听器发布(启动)的时候,定义的事件类型是ApplicationStartedEvent,都不匹配。

    public void starting() {this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args));
    }
    
  • 若不是SmartApplicationListener的子类

    return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
    

    declaredEventType 这个变量就是监听器父类(包括直接父类(父接口)、间接父类(父接口))实现ApplicationListener所对应的泛型事件类型,针对直接父类、间接父类分别举一个监听器的实例进行说明

    • 直接父类

      AnsiOutputApplicationListener这个监听器

      public class AnsiOutputApplicationListenerimplements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {//......
      }
      
    
    `AnsiOutputApplicationListener`直接实现了`ApplicationListener`接口,对应的泛型事件是`ApplicationEnvironmentPreparedEvent`,所以对应的this.declaredEventType就是`ApplicationEnvironmentPreparedEvent`。- 间接父类`ConfigFileApplicationListener`这个监听器```javapublic class ConfigFileApplicationListenerimplements EnvironmentPostProcessor, SmartApplicationListener, Ordered {//......}
    

    ConfigFileApplicationListener实现的3个接口EnvironmentPostProcessor、SmartApplicationListener、Ordered,但是这3个接口中都没有ApplicationListener接口,所以按照顺序找他们的间接父类(接口),EnvironmentPostProcessor没有父类(接口),不用管,但是如果它有的话,就需要接着往上找,直接没有实现的接口和继承的父类为止;SmartApplicationListener有一个父接口,并且这个父类口就是ApplicationListener,所以所以对应的this.declaredEventType就是ApplicationEvent。

    public interface SmartApplicationListener extends  ApplicationListener<ApplicationEvent>, Ordered {boolean supportsEventType(Class<? extends ApplicationEvent> eventType);boolean supportsSourceType(Class<?> sourceType);}
    

    下面进行具体的源码分析。

    这段代码会被执行,关键就在于declaredEventType变量,而这个变量是在执行构造方法的时候被赋值的

    public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {Assert.notNull(delegate, "Delegate listener must not be null");this.delegate = (ApplicationListener<ApplicationEvent>) delegate;this.declaredEventType = resolveDeclaredEventType(this.delegate);
    }
    

    所以要看 resolveDeclaredEventType(this.delegate)这个方法。

    这个方法的实现比较复杂,这里先直接给出整个方法实现逻辑,在进行解析,有兴趣的读者就看看,觉得看起来比较困难的读者就了解一下这个方法的实现逻辑即可。

    private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {//解析监听器的事件类型ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass());if (declaredEventType == null || declaredEventType.isAssignableFrom(ResolvableType.forClass(ApplicationEvent.class))) {Class<?> targetClass = AopUtils.getTargetClass(listener);if (targetClass != listener.getClass()) {declaredEventType = resolveDeclaredEventType(targetClass);}}return declaredEventType;
    }
    

    先看resolveDeclaredEventType(listener.getClass())这个方法的实现

      static ResolvableType resolveDeclaredEventType(Class<?> listenerType) {ResolvableType resolvableType = ResolvableType.forClass(listenerType).as(ApplicationListener.class);return (resolvableType.hasGenerics() ? resolvableType.getGeneric() : null);}
    

    先看ResolvableType.forClass(listenerType)这个方法,实现如下:

     public static ResolvableType forClass(Class<?> clazz) {return new ResolvableType(clazz);}//ResolvableType构造方法private ResolvableType(Class<?> clazz) {this.resolved = (clazz != null ? clazz : Object.class);this.type = this.resolved;this.typeProvider = null;this.variableResolver = null;this.componentType = null;this.hash = null;}
    

    所以ResolvableType.forClass(listenerType)这个方法就创建了一个ResolvableType的实例对象, type为监听器类型(例如ConfigFileApplicationListener)。

    ResolvableType.forClass(listenerType).as(ApplicationListener.class)种的as(ApplicationListener.class)实现如下:

    携程

      public ResolvableType as(Class<?> type) {//这个判定就不解释了if (this == NONE) {return NONE;}if (ObjectUtils.nullSafeEquals(resolve(), type)) {return this;}for (ResolvableType interfaceType : getInterfaces()) {ResolvableType interfaceAsType = interfaceType.as(type);if (interfaceAsType != NONE) {return interfaceAsType;}}return getSuperType().as(type);}//NONE定义public static final ResolvableType NONE = new ResolvableType(null, null, null, 0);
    

    先看方法中的第2个判定

      if (ObjectUtils.nullSafeEquals(resolve(), type)) {return this;}
    

    resolve()方法的实现如下:

      public Class<?> resolve() {//调用重载的resolve(Class<?> fallback)方法return resolve(null);}public Class<?> resolve(Class<?> fallback) {return (this.resolved != null ? this.resolved : fallback);}
    

    this.resolved执行ResolvableType.forClass(listenerType)的时候被赋值,所以ResolvableType的 resolve()方法就返回ResolvableType的resolved变量。

    在看ObjectUtils.nullSafeEquals方法,继续跟踪源码

     public static boolean nullSafeEquals(Object o1, Object o2) {if (o1 == o2) {return true;}if (o1 == null || o2 == null) {return false;}if (o1.equals(o2)) {return true;}if (o1.getClass().isArray() && o2.getClass().isArray()) {return arrayEquals(o1, o2);}return false;}
    

    这个方法实现也很简单,就是根据o1和o2两个Object对象进行逻辑判定,返回true或者false。具体逻辑写出来太麻烦了,读者自行debug即可,但是有一点是需要点出来的,o1和o2两个Object对象相等(==或者equals)就会返回true,进而

      if (ObjectUtils.nullSafeEquals(resolve(), type)) {return this;}
    

    这段代码就会返回this,也就是当前的ResolvableType对象。

    假设ResolvableType.forClass(listenerType).as(ApplicationListener.class)中的listenerTypeConfigFileApplicationListener,代码就会执行到

      for (ResolvableType interfaceType : getInterfaces()) {ResolvableType interfaceAsType = interfaceType.as(type);if (interfaceAsType != NONE) {return interfaceAsType;}}
    

    跟踪getInterfaces()的源码

    public ResolvableType[] getInterfaces() {//resolve()不再解释,前面解释过了,就是获取ResolvableType的resolved变量,这里就是//ConfigFileApplicationListener的class对象Class<?> resolved = resolve();if (resolved == null || ObjectUtils.isEmpty(resolved.getGenericInterfaces())) {return EMPTY_TYPES_ARRAY;}if (this.interfaces == null) {this.interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved), asVariableResolver());}return this.interfaces;}//EMPTY_TYPES_ARRAY定义private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0];
    

    resolved.getGenericInterfaces()方法,就相当于是Class.getGenericInterfaces()方法,以Type的形式返回本类直接实现的接口.这样就包含了泛型参数信息(有的话),ConfigFileApplicationListener实现的接口有3个

    • EnvironmentPostProcessor

    • SmartApplicationListener(继承ApplicationListener, Ordered)

    • Ordered

      所以resolved == null || ObjectUtils.isEmpty(resolved.getGenericInterfaces()判定结果就是 false。

      接着往下走,到了

    if (this.interfaces == null) {this.interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved), asVariableResolver());}
    

    this.interfaces 肯定是为null的,因为在执行ResolvableType.forClass(listenerType)的时候只调用了ResolvableType的构造方法,并未给interfaces变量赋值。

    先看SerializableTypeWrapper.forGenericInterfaces(resolved)这个方法,实现如下:

    //注意type在这里就是传入的resolved,ConfigFileApplicationListener的Class对象public static Type[] forGenericInterfaces(final Class<?> type) {//定义数组Type[] result = new Type[type.getGenericInterfaces().length];//做一个循环,给result数组赋值for (int i = 0; i < result.length; i++) {final int index = i;//SimpleTypeProvider implements TypeProvider,重写了getType()方法result[i] = forTypeProvider(new SimpleTypeProvider() {@Overridepublic Type getType() {return type.getGenericInterfaces()[index];}});}return result;}
    

    forTypeProvider方法按照ConfigFileApplicationListener实现接口的顺序,每次for循环返回一个父接口,所以forGenericInterfaces方法是以Type数组的形式返回指定Class对象的父接口。

    forTypeProvider方法实现如下:

     static Type forTypeProvider(final TypeProvider provider) {Assert.notNull(provider, "Provider must not be null");//provider.getType()实际调用的方法是SimpleTypeProvider类重写的getType方法/*new SimpleTypeProvider() {@Overridepublic Type getType() {return type.getGenericInterfaces()[index];}});*///很显然provider.getType() instanceof Serializable为trueif (provider.getType() instanceof Serializable || provider.getType() == null) {return provider.getType();}//后面代码简单解释一下,我们这里用不太到//从cache(cache这里可以简单理解为缓存)中取,有就取,并返回;没有继续执行后续代码Type cached = cache.get(provider.getType());if (cached != null) {return cached;}//cache中也拿不到数据时,就通过反射,生成实例,人为给cache填充数据for (Class<?> type : SUPPORTED_SERIALIZABLE_TYPES) {if (type.isAssignableFrom(provider.getType().getClass())) {ClassLoader classLoader = provider.getClass().getClassLoader();Class<?>[] interfaces = new Class<?>[] {type, SerializableTypeProxy.class,                     Serializable.class};InvocationHandler handler = new TypeProxyInvocationHandler(provider);//通过发射生成Type实例cached = (Type) Proxy.newProxyInstance(classLoader, interfaces, handler);cache.put(provider.getType(), cached);return cached;}}throw new IllegalArgumentException("Unsupported Type class: " + provider.getType().getClass().getName());}
    

    SerializableTypeWrapper.forGenericInterfaces(resolved)方法分析完了,再看asVariableResolver()的源码实现

      VariableResolver asVariableResolver() {if (this == NONE) {return null;}return new DefaultVariableResolver();}
    

    这里很简单,就是单纯的创建一个DefaultVariableResolver对象。

    再看下forTypes方法实现:

    //循环调用重载的2个参数的forType方法private static ResolvableType[] forTypes(Type[] types, VariableResolver owner) {ResolvableType[] result = new ResolvableType[types.length];for (int i = 0; i < types.length; i++) {result[i] = forType(types[i], owner);}return result;}//2个参数forType方法,直接调用3个参数的forType方法static ResolvableType forType(Type type, VariableResolver variableResolver) {return forType(type, null, variableResolver);}//3个参数的forType方法static ResolvableType forType(Type type, TypeProvider typeProvider, VariableResolver variableResolver) {if (type == null && typeProvider != null) {type = SerializableTypeWrapper.forTypeProvider(typeProvider);}if (type == null) {return NONE;}//代码会执行到这个逻辑,返回新创建的ResolvableType的实例if (type instanceof Class) {return new ResolvableType(type, typeProvider, variableResolver, (ResolvableType) null);}cache.purgeUnreferencedEntries();ResolvableType key = new ResolvableType(type, typeProvider, variableResolver);ResolvableType resolvableType = cache.get(key);if (resolvableType == null) {resolvableType = new ResolvableType(type, typeProvider, variableResolver, key.hash);cache.put(resolvableType, resolvableType);}return resolvableType;}
    

    所以getInterfaces()方法一个ResolvableType类型的数组,数组中每个ResolvableType变量的一次为

    • EnvironmentPostProcessor

    • SmartApplicationListener(继承ApplicationListener, Ordered)

    • Ordered

​ 到这里的话,ResolvableTypeas方法中的getInterfaces()就分析完了。

public ResolvableType as(Class<?> type) {if (this == NONE) {return NONE;}if (ObjectUtils.nullSafeEquals(resolve(), type)) {return this;}//循环回调as方法for (ResolvableType interfaceType : getInterfaces()) {//第一次 :EnvironmentPostProcessor,返回NONEResolvableType interfaceAsType = interfaceType.as(type);if (interfaceAsType != NONE) {return interfaceAsType;}}return getSuperType().as(type);
}

第一次循环遍历的时候interfaceType的type变量为EnvironmentPostProcessor的Class对象,在回调as方法时候,getInterfaces()获取的ResolvableType数组size=0,会执行getSuperType().as(type)这句代码,getSuperType()会返回NONE,实现如下:

public ResolvableType getSuperType() {Class<?> resolved = resolve();//EnvironmentPostProcessor无继承父类,resolved.getGenericSuperclass()为null,所以//返回NONEif (resolved == null || resolved.getGenericSuperclass() == null) {return NONE;}if (this.superType == null) {this.superType = forType(SerializableTypeWrapper.forGenericSuperclass(resolved), asVariableResolver());}return this.superType;
}

返回NONE之后调用as方法,返回的也是NONE,所以:第一次循环遍历interfaceType.as(type)返回值为NONE

第二次循环遍历的时候interfaceType的type变量为SmartApplicationListener的Class对象,回调as方法时候直接以代码注释的方式为读者写出来,比较直观一些,就不分析,前面已经分析过了。

//注意此时ResolvableType对象的type,resolved都是基于SmartApplicationListener的
//type还是ApplicationListener.class类型的
public ResolvableType as(Class<?> type) {//判定结果为falseif (this == NONE) {return NONE;}//判定结果为falseif (ObjectUtils.nullSafeEquals(resolve(), type)) {return this;}//getInterfaces()会获取size=2的ResolvableType数组//ResolvableType[0]的type、resolved为ApplicationListener//ResolvableType[1]的type、resolved为Ordered//第一次循环遍历的时候回调as方法时候ObjectUtils.nullSafeEquals(resolve(), type)为true,//所以会直接返回当前的ResolvableType对象,那就!= NONE,所以会返回ApplicationListener对应的//ResolvableType对象for (ResolvableType interfaceType : getInterfaces()) {ResolvableType interfaceAsType = interfaceType.as(type);if (interfaceAsType != NONE) {return interfaceAsType;}}return getSuperType().as(type);
}

第二次循环遍历的时候已经有了返回值,那第三次循环遍历就不会再执行了,所以ConfigFileApplicationListener对应的declaredEventType就是ApplicationEvent

到这里的话resolveDeclaredEventType(this.delegate)这个方法就基本分析完了,读者可以选用其他的监听器走一遍代码,加深自己的理解。

getApplicationListeners(event, type)也已经分析完了,这个方法的结果和方法中传入的event是息息相关的。

springBoot启动事件监听机制相关推荐

  1. Springboot事件监听机制:工作原理

    目录 前言 1.观察者模式 1.1观察者模式的核心元素 1.2观察者模式的工作流程 2.springboot事件监听机制的基本工作原理 2.1事件发布器是什么时候在哪里产生的呢? 2.2事件监听器是什 ...

  2. Spring5源码 - 13 Spring事件监听机制_@EventListener源码解析

    文章目录 Pre 概览 开天辟地的时候初始化的处理器 @EventListener EventListenerMethodProcessor afterSingletonsInstantiated 小 ...

  3. Spring5源码 - 11 Spring事件监听机制_源码篇

    文章目录 pre 事件监听机制的实现原理[观察者模式] 事件 ApplicationEvent 事件监听者 ApplicationEvent 事件发布者 ApplicationEventMultica ...

  4. Ⅵ:zookeeper的Watcher事件监听机制

    2021最新zookeeper系列 ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤ ...

  5. spring中的事件监听机制

    Spring event listener 介绍 example 简单原理解释 自定义事件.监听和发布 事件 监听器 发布者 测试 更加一般的事件 @EventListener原理 介绍 exampl ...

  6. Spring容器的事件监听机制(简单明了的介绍)

    文章目录 前言 事件 1. 定义事件 2. 定义监听器 3. 定义发布器 Spring容器的事件监听机制 1.事件的继承类图 监听器的继承类图 总结 前言 上一篇我们介绍了SpringFactorie ...

  7. java中事件监听_Java中的事件监听机制

    鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...

  8. Java中事件监听机制

    Java中事件监听机制 一.事件监听机制的定义 要想了解Java中的事件监听机制,首先就要去了解一下在Java中事件是怎样去定义的呢!在使用Java编写好一个界面后,我们就会对界面进行一些操作,比如, ...

  9. 关于事件监听机制的总结(Listener和Adapter)

    记得以前看过事件监听机制背后也是有一种设计模式的.(设计模式的名字记不清了,只记得背后实现的数据结构是数组.) 附上事件监听机制的分析图: 一个事件源可以承载多个事件(只要这个事件源支持这个事件就可以 ...

最新文章

  1. 【iOS Tips】002-实现“简单单例模式”的几种方法?
  2. Hive Lateral View、视图、索引
  3. Linux 下 mail、mailx 和 sendmail、postfix的区别
  4. mysql的单行注释_MySQL基础--会这些就够了
  5. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性
  6. python123测验7程序题答案_Python语言程序设计 Python123 测验7: 文件和数据格式化(编程题)...
  7. 发一个多CPU中进程与CPU绑定的例子
  8. Nacos系列:欢迎来到Nacos的世界!
  9. JavaSE网络编程练习
  10. 伯努利方程(压力与流量的关系)
  11. Scrum板与Kanban如何抉择?vfmzulfdr板与按照ftjzox
  12. 东财《领导科学X》综合作业
  13. 《数字图像处理》第三章学习总结感悟1:灰度变换与空间滤波概念及常用灰度变换方法介绍
  14. Harmonious Rectangle(dfs 打表)
  15. tensorflow的GPU加速计算
  16. Linux下删除特殊字符的文件或文件夹
  17. byteTrack数据集categories不规范带来的问题
  18. 6-75 绘制多叶玫瑰线
  19. vue项目实现文件下载中心:下载、取消下载、列表展示
  20. Multi-Object Tracking with Multiple Cues and Switcher-Aware Classification 论文笔记

热门文章

  1. DeeperNetwork2022 新年献词:邀您共赴,WEB3.0的星辰大海
  2. 【厚积薄发系列】C++项目总结16—单例模式释放时机导致的崩溃问题分析
  3. 上班摸鱼小游戏—推筒子
  4. mac npm 相关命令
  5. 正则表达式常用验证及打油诗一首
  6. 硬笔书法课视频教程课件练字课程网课成人毛笔写字教学小学生少儿
  7. Elasticsearch实战 | match_phrase搜不出来,怎么办?
  8. oracle10.2精简,请问版主和高手们,Oracle 10.2 完美精简版客户端下载-30M如何使用?...
  9. 智能车竞赛:关于车模系列的价格调整
  10. 第十八届全国大学智能车竞赛车模作品中的电子模块: 白名单与黑名单