SpringBoot实战分析(三)监听器分析

程序入口(SpringApplication)

SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();

监听器的过程

-->程序启动

-->调用getRunListeners(args)获取SpringApplicationRunListeners实例

-->getSpringFactoriesInstances()获取Spring工厂实例

-->loadFactoryNames()通过classLoader加载工厂实例

-->loadSpringFactories() 循环加载/META-INF/spring.factories中的类,组成集合返回

-->createSpringFactoriesInstances()根据加载文件返回的类名创建工厂实例,反射

-->listeners.starting()启动监听器

-->multicastEvent(ApplicationEvent event)组播ApplicationEvent事件

-->getApplicationListeners()判断监听器类型是否与当前监听器类型相同

-->retrieveApplicationListeners(eventType, sourceType, retriever)检索给定事件和源类型的应用程序监听器。

-->supportsEvent(listener, eventType, sourceType)确定给定的监听器是否支持给定的事件。

-->GenericApplicationListenerAdapter(ApplicationListener<?> delegate)为给定的委托创建一个新的GenericApplicationListener。

-->resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener)发布事件监听

-->supportsEventType(eventType)从指定类型解析事件

-->结束

断点跟踪

1.获取监听

private SpringApplicationRunListeners getRunListeners(String[] args) {
    //定义class数组
    Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    //创建SpringApplicationRunListeners 对象
    return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
        SpringApplicationRunListener.class, types, this, args));
}

2.获取spring工厂实例

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
    Class<?>[] parameterTypes, Object... args) {
    // 类加载器
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    // Use names and ensure unique to protect against duplicates
    // 这个返回值是 META-INF/spring.factories 中定义的 父节点
    // names的返回值 传送门7号
    Set<String> names = new LinkedHashSet<>(
    SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    //内部循环初始化 names的构造器
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
    classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

3.加载工厂

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

通过加载META-INF/spring.factories文件,扫描文件,文件内容传送门4号

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    //从cache 实例的结果集 是Null 因为当前的cache 是空的。
   //  cache 实现 new ConcurrentReferenceHashMap<>()
    MultiValueMap<String, String> result = cache.get(classLoader);
    if (result != null) {
        return result;
    }

    try {
        // urls 返回值 见传送门2号
        Enumeration<URL> urls = (classLoader != null ?
               // 获取 META-INF/spring.factories 中的资源
               //  FACTORIES_RESOURCE_LOCATION = META-INF/spring.factories
                //classLoader 不是null  走getResources方法
                //见传送门1号
                classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        result = new LinkedMultiValueMap<>();
       //循环处理urls中的元素
        while (urls.hasMoreElements()) {
            // 获取元素
           // 第一个文件url地址 传送门3号  
           // 第二个文件url地址  传送门3号
           // 后续文件 同上
            UrlResource resource = new UrlResource(url);
           //解析文件 把文件内容变成配置属性
           // 传送门4号
            Properties properties = PropertiesLoaderUtils.loadProperties(resource);
            //循环解析并把结果放到result中
            //传送门5号
            for (Map.Entry<?, ?> entry : properties.entrySet()) {
                List<String> factoryClassNames = Arrays.asList(
                        StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));
                result.addAll((String) entry.getKey(), factoryClassNames);
            }
        }
       //缓存类加载器和文件解析的结果集
       // map.put
        cache.put(classLoader, result);
        // 结果 为13条
        return result;
    }
    catch (IOException ex) {
        throw new IllegalArgumentException("Unable to load factories from location [" +
                FACTORIES_RESOURCE_LOCATION + "]", ex);
    }
}

4.创建Spring工厂实例

private <T> List<T> createSpringFactoriesInstances(Class<T> type,
        Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
        Set<String> names) {
    List<T> instances = new ArrayList<>(names.size());
   // 循环处理names的值
    for (String name : names) {
        try {
            Class<?> instanceClass = ClassUtils.forName(name, classLoader);
            Assert.isAssignable(type, instanceClass);
            Constructor<?> constructor = instanceClass
                    .getDeclaredConstructor(parameterTypes);
            T instance = (T) BeanUtils.instantiateClass(constructor, args);
            instances.add(instance);
        }
        catch (Throwable ex) {
            throw new IllegalArgumentException(
                    "Cannot instantiate " + type + " : " + name, ex);
        }
    }
    return instances;
}

public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
        throws ClassNotFoundException, LinkageError {

    Assert.notNull(name, "Name must not be null");

    Class<?> clazz = resolvePrimitiveClassName(name);
    if (clazz == null) {
       // 缓存值为空 无缓存    new HashMap<>(64);
        clazz = commonClassCache.get(name);
    }
    if (clazz != null) {
        return clazz;
    }
  //3个if判断
    。。。。。。
 //通过加载器加载name值对应的类
    ClassLoader clToUse = classLoader;
    if (clToUse == null) {
        clToUse = getDefaultClassLoader();
    }
    try {
       //反射
        return (clToUse != null ? clToUse.loadClass(name) : Class.forName(name));
    }
    catch (ClassNotFoundException ex) {
        int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
        if (lastDotIndex != -1) {
            String innerClassName =
                    name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
            try {
                return (clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName));
            }
            catch (ClassNotFoundException ex2) {
                // Swallow - let original exception get through
            }
        }
        throw ex;
    }
}

5.加载监听器类

listeners.starting();断点进入

获取EventPublishingRunListener调用构造方法
public EventPublishingRunListener(SpringApplication application, String[] args) {
    this.application = application;
    this.args = args;
    this.initialMulticaster = new SimpleApplicationEventMulticaster();
   // 给initialMulticaster 添加listener
    for (ApplicationListener<?> listener : application.getListeners()) {
        this.initialMulticaster.addApplicationListener(listener);
    }
}

6.启动监听

添加完监听器之后,调用listeners.starting();

调用的是SpringApplicationRunListeners中的:

public void starting() {
    for (SpringApplicationRunListener listener : this.listeners) {
        listener.starting();
    }
}

实现类调用EventPublishingRunListener的方法:

@Override
public void starting() {
   //这个位置版本不同,写法可能不一样
    this.initialMulticaster.multicastEvent(
            new ApplicationStartingEvent(this.application, this.args));
}

在上面代码中创建了一个ApplicationStartingEvent事件,将springapplicationthis.application传入,因此监听的时候获取的是SpringApplication实例。

执行SimpleApplicationEventMulticaster中的multicastEvent()方法:

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

执行SimpleApplicationEventMulticaster中的multicastEvent方法:

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   //注意getApplicationListeners获取对应的事件监听器
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();
        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);

    // Quick check for existing entry on ConcurrentHashMap...
    // 快速检查ConcurrentHashMap的现有条目。
    ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
    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 ListenerRetriever
        synchronized (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 necessary
        return retrieveApplicationListeners(eventType, sourceType, null);
    }
}

//实际上检索给定事件和源类型的应用程序监听器是否匹配。

private Collection<ApplicationListener<?>> retrieveApplicationListeners(
        ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {

    LinkedList<ApplicationListener<?>> allListeners = new LinkedList<>();
    Set<ApplicationListener<?>> listeners;
    Set<String> listenerBeans;
    synchronized (this.retrievalMutex) {
        //这个listeners集合就是前文提到的从配置中过滤的10个监听器类
       //传送门8号
        listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
       //空值
        listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
    }
   //循环10个listeners调用supportsEvent方法
    for (ApplicationListener<?> listener : listeners) {
        if (supportsEvent(listener, eventType, sourceType)) {
            if (retriever != null) {
                retriever.applicationListeners.add(listener);
            }
            allListeners.add(listener);
        }
    }

    省略。。。

    AnnotationAwareOrderComparator.sort(allListeners);
    return allListeners;
}
protected boolean supportsEvent(
        ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
   //判断listener的类型是否是GenericApplicationListener的一个实例
    GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
            (GenericApplicationListener) listener :
//适配模式
 new GenericApplicationListenerAdapter(listener));
    return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}

调用newGenericApplicationListenerAdapter()

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

@Nullable
private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {
    ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass());
    //判断declaredEventType是否是ApplicationEvent事件
    if (declaredEventType == null || declaredEventType.isAssignableFrom(
            ResolvableType.forClass(ApplicationEvent.class))) {
        //获取传入的监听器类
        Class<?> targetClass = AopUtils.getTargetClass(listener);
        if (targetClass != listener.getClass()) {
            declaredEventType = resolveDeclaredEventType(targetClass);
        }
    }
    return declaredEventType;
}

调用resolveDeclaredEventType()方法获取指定类继承的父类或实现接口时传递的泛型对应的类型

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

调用supportsEventType方法

@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
    if (this.delegate instanceof SmartApplicationListener) {
        Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
        return (eventClass != null && ((SmartApplicationListener) this.delegate).
//调用supportsEventType(),实际是调用自己
supportsEventType(eventClass));
    }
    else {
        return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
    }
}

遍历所有的监听器,如果该监听器监听的事件为传递的事件或传递事件的父类则表示该监听器支持指定事件。


传送门1

// name =  META-INF/spring.factories
public Enumeration<URL> getResources(String name) throws IOException {
    @SuppressWarnings("unchecked")
    Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
    if (parent != null) {
        tmp[0] = parent.getResources(name);
    } else {
        tmp[0] = getBootstrapResources(name);
    }
    tmp[1] = findResources(name);

    return new CompoundEnumeration<>(tmp);
}

全路径(本地路径,根据配置不同路径不同)

jar:file:/D:/maven/package/org/springframework/boot/spring-boot/2.0.2.RELEASE/spring-boot-2.0.2.RELEASE.jar!/META-INF/spring.factories

传送门2

传送门3





传送门4

value为当前key对应的属性值以逗号分隔字符串。


文件内容

# PropertySource Loaders

org.springframework.boot.env.PropertySourceLoader=\

org.springframework.boot.env.PropertiesPropertySourceLoader,\

org.springframework.boot.env.YamlPropertySourceLoader


# Run Listeners

org.springframework.boot.SpringApplicationRunListener=\

org.springframework.boot.context.event.EventPublishingRunListener


# Error Reporters

org.springframework.boot.SpringBootExceptionReporter=\

org.springframework.boot.diagnostics.FailureAnalyzers


# Application Context Initializers

org.springframework.context.ApplicationContextInitializer=\

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\

org.springframework.boot.context.ContextIdApplicationContextInitializer,\

org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\

org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer


# Application Listeners

org.springframework.context.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.context.logging.ClasspathLoggingApplicationListener,\

org.springframework.boot.context.logging.LoggingApplicationListener,\

org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener


# Environment Post Processors

org.springframework.boot.env.EnvironmentPostProcessor=\

org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\

org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\

org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor


# Failure Analyzers

org.springframework.boot.diagnostics.FailureAnalyzer=\

org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\

org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer


# FailureAnalysisReporters

org.springframework.boot.diagnostics.FailureAnalysisReporter=\

org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

传送门5




传送门6



传送门7


names的值经过下面函数处理

default V getOrDefault(Object key, V defaultValue) {
    V v;
    return (((v = get(key)) != null) || containsKey(key))
        ? v
        : defaultValue;
}

传送门8号






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章