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

[] 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[ ]类型 。
SpringApplicationRunListener 源码解析
接口 SpringApplicationRunListener 是 SpringApplication 的 run 方法监听器 。 上节提到了SpringApplicationRunListener 通过 SpringFactoriesL oader 加载 , 并且必须声明一个公共构造函数 , 该函数接收 SpringApplication 实例和 String[ ]的参数 , 而且每次运行都会创建一个新的实例 。
SpringApplicationRunListener 提供了-系列的方法 , 用户可以通过回调这些方法 , 在启动各个流程时加入指定的逻辑处理 。 下面我们对照源代码和注释来了解一下该接口都定义了哪些待实现的方法及功能 。
public interface SpringApplicationRunL istener {// 当 run 方法第- 次被执行时 , 会被立即调用 , 可用于非常早期的初始化工作 default voidstarting(){};//当 environment 准备完成 ,在 Appl icationContext 创建之前 ,该方法被调用 default voidenvironmentPrepared(Conf igurableEnvironment environment) {};//当 ApplicationContext 构建完成 ,资源还未被加载时 ,该方法被调用 default voidcontextPrepared(ConfigurableApplicationContext context) {}// 当 Appl icat ionContext 加 载 完 成,未 被 刷 新 之 前,该 方 法 被 调 用 default voidcontextLoaded(ConfigurableApplicationContext context) {};//当 ApplicationContext 刷新并启动之后, CommandL ineRunner 和 Appl icat ionRunner 未被调用之前 ,该方法被调用default void started(Conf igurableApplicationContext context) {};//当所有准备工作就绪 , run 方法执行完成之前 ,该方法被调用default void running(ConfigurableApplicationContext context) {};//当应用程序出现错误时 , 该方法被调用default void failed(ConfigurableApplicationContext context, Throwable exception) {};}我们通过源代码可以看出 , SpringApplicationRunListener 为 run 方法提供了各个运行阶段的监听事件处理功能 。 需要注意的是 , 该版本中的接口方法定义使用了 Java8 的新特性 , 方法已采用 default 声明并实现空方法体 , 表示这个方法的默认实现 , 子类可以直接调用该方法 , 也可以选择重写或者不重写 。
图 4-2 展示了在整个 run 方法的生命周期中 SpringApplicationRunListener 的所有方法所处的位置 , 该图可以帮助我们更好地学习 run 方法的运行流程 。 在前面 run 方法的代码中已经看到相关监听方法被调用 , 后续的源代码中也将涉及对应方法的调用 , 我们可参考此图以便理解和加深记忆 。
SpringBoot运行流程源码分析:run方法流程及监听器文章插图
实现类 EventPublishingRunListener
EventPublishingRunL istener 是 SpringBoot 中针对 SpringApplicationRunListener 接口的唯内建实现EventPublishingRunL istener使用内置的SimpleApplicationEventMulticaster来广播在上下文刷新之前触发的事件 。