SpringBoot运行流程源码分析:run方法流程及监听器( 二 )

在整体了解了整个 run 方法运行流程及核心代码后 , 下面我们针对具体的程进行讲解 。
SpringApplicationRunListener 监听器 监听器的配置与加载
让我们忽略 Spring Boot 计 时和统计的辅助功能 , 直接来看 SpringApplicationRunListeners获取和使用 SpringApplicationRunL isteners可以理解为一个 SpringApplicationRunListener的容器 , 它将 SpringApplicationRunListener 的集合以构造方法传入 ,并赋值给其 listeners成员变量 , 然后提供了针对 listeners 成员变量的各种遍历操作方法 , 比如 , 遍历集合并调用对应的 starting、started、 running 等方法 。
SpringApplicationRunListeners 的构建很简单 , 图 4-1 中调用的 getRunListeners 方法也只是调用了它的构造方法 。 SpringApplication 中 getRunListeners 方法代码如下 。
private SpringApplicationRunListeners getRunListeners(String[] args) {//构造 Class 数组Class[] types = new Class[] { SpringApplication. class, String[].cla/调用 SpringAppl icat ionRunL isteners 构造方法return new SpringApplicationRunListeners(logger, getSpringFactoriesInstancesSpringApplicationRunListener .class, types, this, args));}SpringApplicationRunListeners 构 造 方 法 的 第 二 个 参 数 便 是 SpringApplicationRunListener 的 集 合,SpringApplication 中 调 用 构 造 方 法 时 该 参 数 是 通 过getSpringFactoriesInstances 方法获取的 , 代码如下 。 privateCollection getSpringF actoriesInstances(Class type,Class[] parameterTypes, object... args) {//加 META- TNE/sprina. factori es 中对应监听器的配并将结果存 F'set 中(去重)Set names= newLinkedHashSet<>(个命的能直 , SpringF actoriesl oader. loadFactoryNames(type, classloader));/文悯化监听器List instances = createSpringFactories Instances (type, parameterTypes,classLoader, args, nam排序Annotat ionAwareOrderComparator .sort(instances);eturn instances ; }通过方法名便可得知 , getSpringFactoriesInstances 是用来获取 factories 配置文件中的注册类 , 并进行实例化操作 。
关于通过 SpringFactoriesL oader 获取 META-INF/spring.factories 中对应的配置 , 前面章节已经多次提到 , 这里不再赘述 。
SpringApplicationRunListener 的注册配置位于 spring-boot 项目中的 spring.factories 文件内 , Spring Boot 默认仅有- -个监听器进行了注册 , 关于其功能后面会专门讲到 。
# RunListenersorg. springframework. boot.SpringApplicationRunListener=\org. springframework. boot. context.event.EventPublishingRunL istener我们继续看实例化监听器的方法 createSpringFactoriesInstances 的源代码 。 privateList createSpringFactoriesInstances(Class typeClass[] parameterTypes, ClassLoader classLoader, Object[] args,Set names) {List instances = new ArrayList<>(names.size());for (String name : names)Class instanceClass = ClassUtils . forName(name, classLoader);Assert.isAssignable(type, instanceClass);//获取有参构造器Constructor constructor = instanceClass . getDeclaredConstructor(parameterTypes);T instance = (T) BeanUtils. instant iateClass(constructor, args);instances . add(instance);return instances;}在上面的代码中 , 实例化监听器时需要有一-个默认的构造方法 ,且构造方法的参数为Class[ ] parameterTypes 。 我们向上追踪该参数的来源 , 会发现该参数的值为 Class 数组,数 组 的 内 容 依 次 为 SpringApplication.class 和 String[ ].class。也 就 是 说, SpringApplicationRunL istener 的实现类必须有默认的构造方法 , 且构造方法的参数必须依次为 SpringApplication 和 String[ ]类型 。