springboot初始化逻辑_SpringBoot日志源码解析:日志监听器的执行

LoggingApplicationListener 的执行

LoggingApplicationListener 的主要作用是配置LoggingSystem, 如果 环境 包含 loggingconfig 属性,LoggingApplicationListener 将用于引导 日志记录系统,否则使用默认配置。

如果环境包含 logging.level.*和日志记录组,则可以使用 logging.group 定义日志记录级别。

关于 LoggingApplicationL istener 的重点功能我们后面章节再进行讲解。

LoggingApplicationListener 实现自 GenericApplicationListener 接口,具有监听器的特性。

因此,执行 EventPublishingRunListener 广播事件之后,LoggingApplicationListener 便会监听到对应的事件并执行 onApplicationEvent 方法中的逻辑判断,有针对性地处理不同的事件,相关代码如下。

@Overridepublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationStartingEvent) {// springboot 启动时触发onApplicationStartingEvent( (ApplicationStartingEvent) event);} else if (event instanceof ApplicationEnvironmentPreparedEvent) {// Environment 环境准备初级阶段触发onApplicationEnvironmentPreparedEvent( (Applicat ionEnvironmentPrepared-Event) event);} else if (event instanceof ApplicationPreparedEvent) {//应用上下文准备完成,但未刷新时触发onApplicationPreparedEvent( (Applicat ionPreparedEvent) event);else if (event instanceof ContextClosedEvent&& ((ContextClosedEvent) event). getApplicationContext() . getParent() == null) {//容器关闭时处理onContextClosedEvent( );} else if (event instanceof ApplicationFailedEvent) {//启动失败时处理onApplicationFailedEvent();}}

以上代码中的事件处理基本涵盖了 Spring Boot 启动的不同阶段和不同状况,比如 SpringBoot 刚刚启动阶段、环境准备初级阶段、应用上下文准备完成阶段、容器关闭阶段、应用程序启动失败等。后面章节我们会对这些过程中日志系统是如何处理的进行详解介绍。

8ef9749f379b935e57073ff9630d3355.png

ApplicationStartingEvent 事件处理

在 Spring Boot 的启动过程中,通过 SpringApplicationRunListeners 类间接的调用了EventPublishingRunListener 中 的 各 类 事 件 的 发 布 方 法 , 最 终 被 LoggingApplicationListener 监听并进行处理。在后续的讲解中,我们省略这个中间调用过程,直接讲解 Logging-ApplicationL istener 接收到事件后的处理。

Spring Boot 刚 刚 启 动 时 发 布 了 ApplicationStartingEvent 事 件 , LoggingApplication-Listener 中的 onApplicationStartingEvent 方法便被调用了,该方法源码如下。

private void onApplicat ionStartingEvent(ApplicationStartingEvent event)this .loggingSystem = LoggingSystem. get(event . getSpringApplication(). getClassLoader()) ;this. loggingSystem. beforeInitialize();}

在 onApplicationStartingEvent 方法中,首先获得一个 LoggingSystem 对象,然后调用对象的 beforelnitialize 方 法进行预初始化操作。也就是说在 Spring Boot 开始启动时,日志系统做了两件事:创建 LoggingSystem 对象和预初始化操作。

LoggingSystem 为日志系统的通用抽象类,其中也提供了获取 LoggingSystem 对象的静态方法。上面 LoggingSystem 的创建便 是调用其 get 方法获得,相关代码如下。

public static LoggingSystem get(ClassLoader classLoader) {//从系统变量中获得 L oggingSystem 的类名String loggingSystem = System. getProperty(SYSTEM PROPERTY);f (StringUtils . hasLength(loggingSystem)) {if (NONE . equals(loggingSystem))return new NoOpLoggingSystem();/如果存在,则通过反射进行对象的初始化return get(classLoader, loggingSystem);// MSYSTEMS 筛选并初始化 LoggingSystem 对象return SYSTEMS . entrySet() . stream(). filter((entry) -> ClassUtils. isPresent(entry . getKey(), classLoader)).map((entry) -> get(classLoader, entry . getValue())). findFirst(). orElseThrow(() -> new IllegalStateException("No suitable logging system located"));}

该方法首先判断系统中是否配置了 LoggingSystem 的配置,存在且不为“none”时,则利用反射机制进行初始化;如果明确配置为"none”,则返回 NoOpL oggingSystem 对象。实例化配置的 L oggingSystem 相关代码如下。

private static LoggingSystem get(ClassLoader classLoader, String loggingSystemClass) {tryClass> systemClass = ClassUtils . forName( loggingSystemClass, classLoader);Constructor> constructor = systemClass . getDeclaredConstructor(Class-Loader.class);constructor . setAccessible(true);return (LoggingSystem) constructor. newInstance(classLoader);} catch (Exception ex) {throw new IllegalStateException(ex);}}

以上代码就是通过获取指定类的构造器,调用其 newInstance 方法来创建 LoggingSystem对象的。

如果系统中不存在该对象的配置,则从 SYSTEMS 筛选获取第一个符合条件的值,然后进行初始化。SYSTEMS 为 L oggingSystem 的静态变量,通过静态代码块进行初始化,相关代码如下。

private static final Map SYSTEMS;static {Map systems = new Linked
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值