SpringBoot怎么把⽇志默认配置好的

1、每个 starter 场景,都会导⼊⼀个核⼼场景 spring-boot-starter

2、核⼼场景引⼊了⽇志的所⽤功能 spring-boot-starter-logging

3、默认使⽤了 logback + slf4j 组合作为默认底层⽇志

4、 ⽇志是系统⼀启动就要⽤ , xxxAutoConfiguration 是系统启动好了以后放好的组件, 后来⽤的。

5、⽇志是利⽤监听器机制配置好的。 ApplicationListener 。

6、⽇志所有的配置都可以通过修改配置⽂件实现。以 logging 开始的所有配置。

这个日志是利用监听器机制实现的,具体如何实现

在Spring Boot里,日志配置主要借助LoggingApplicationListener这个监听器来完成,它会在应用启动的早期阶段就对日志系统进行初始化。下面详细介绍其实现机制:

1. 监听器的注册

LoggingApplicationListener会被自动注册到Spring Boot的应用上下文里。当应用启动时,它会监听ApplicationEnvironmentPreparedEventApplicationPreparedEvent这两个关键事件。

2. 事件监听流程

步骤1:环境准备完成事件(EnvironmentPrepared)
  • 监听器会在应用环境(Environment)准备好之后,立即开始初始化日志系统。
  • 它会读取所有以logging开头的配置属性,像logging.levellogging.file等。
  • 示例配置:
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.file.name=myapp.log
步骤2:应用准备完成事件(Prepared)
  • 在应用上下文(ApplicationContext)创建完成,但还未刷新之前,监听器会完成日志系统的最终配置。
  • 它会检测类路径下的日志实现(例如Logback),并根据检测结果加载相应的配置文件。

3. 配置文件加载规则

  • 默认配置:如果没有自定义配置文件,Logback会使用默认的配置进行输出,比如输出到控制台。
  • 自定义配置:监听器会优先加载带有spring前缀的配置文件,像logback-spring.xml。这类文件支持Spring的占位符和条件配置,例如:
<springProfile name="dev">
    <!-- 开发环境配置 -->
</springProfile>
<springProfile name="prod">
    <!-- 生产环境配置 -->
</springProfile>

4. 日志级别配置原理

  • 监听器会把logging.level配置映射到各个日志记录器(Loggers)。
  • 例如,配置logging.level.org.springframework=WARN会将Spring框架的日志级别设置为WARN。

5. 日志文件配置

  • 监听器支持配置日志文件的位置和滚动策略。
  • 示例配置:
logging.file.name=app.log
logging.file.max-size=10MB
logging.file.max-history=30

6. 与自动配置的协同工作

虽然日志系统在自动配置(AutoConfiguration)之前就已经初始化好了,但后续的组件依然可以通过LoggerFactory来获取日志记录器,因为SLF4J的绑定在启动早期就已经完成了。

7. 关键代码解析

下面是LoggingApplicationListener的简化版工作流程:

public class LoggingApplicationListener implements ApplicationListener<ApplicationEvent>, Ordered {
    
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            // 环境准备好后,初始化日志系统
            initializeLogSystem(event.getEnvironment());
        }
        else if (event instanceof ApplicationPreparedEvent) {
            // 应用上下文准备好后,完成日志系统配置
            finalizeLogSystem(event.getApplicationContext());
        }
    }
    
    private void initializeLogSystem(ConfigurableEnvironment environment) {
        // 从Environment中获取logging相关配置
        LoggingSystem loggingSystem = LoggingSystem.get(ClassLoader.getSystemClassLoader());
        loggingSystem.beforeInitialize();
        // 配置日志级别、文件等
        configureLoggingSystem(environment, loggingSystem);
    }
    
    private void finalizeLogSystem(ConfigurableApplicationContext context) {
        // 加载最终的配置文件(如logback-spring.xml)
        LoggingSystem loggingSystem = LoggingSystem.get(ClassLoader.getSystemClassLoader());
        loggingSystem.initialize();
    }
}

总结

Spring Boot的日志配置之所以能够在应用启动早期就完成,主要依靠LoggingApplicationListener监听关键事件,并与环境配置(Environment)紧密配合。这种实现方式保证了日志系统能够在其他组件需要使用日志之前就完成初始化,同时还支持通过配置文件灵活调整日志行为。

springboot的启动流程

Spring Boot 的启动流程是一个精心设计的过程,涉及多个关键阶段和组件。下面将详细介绍其启动流程:

1. 启动入口:SpringApplication.run()

一切从 main 方法调用 SpringApplication.run() 开始:

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

SpringApplication.run() 是启动的核心方法,负责创建并刷新应用上下文。

2. 创建 SpringApplication 实例

run() 方法内部会创建 SpringApplication 实例,主要完成以下工作:

  1. 推断应用类型
    • 判断应用是 REACTIVESERVLET 还是 NONE 类型。
  1. 查找并加载初始化器(Initializers)
    • META-INF/spring.factories 中加载 ApplicationContextInitializer 实现类,用于在上下文刷新前自定义上下文。
  1. 查找并加载应用监听器(Listeners)
    • META-INF/spring.factories 中加载 ApplicationListener 实现类,监听应用生命周期事件。
  1. 推断主类
    • 确定包含 main 方法的主类。

3. 运行应用:SpringApplication.run()

核心启动逻辑分为以下步骤:

步骤1:创建并配置 ApplicationEnvironment
  • 解析命令行参数,创建 ConfigurableEnvironment
  • 将命令行参数转换为 PropertySource 并添加到环境中。
步骤2:触发 ApplicationEnvironmentPreparedEvent
  • 通知所有 ApplicationListener 环境已准备好。
  • 日志系统在此阶段初始化(通过 LoggingApplicationListener)。
步骤3:创建 ApplicationContext
  • 根据应用类型创建对应的上下文(如 AnnotationConfigServletWebServerApplicationContext)。
  • 设置环境(Environment)和资源加载器。
步骤4:准备上下文(prepareContext()
  • 应用初始化器(Initializers)对上下文进行预处理。
  • 注册主应用类(如 MyApplication)为配置源。
步骤5:刷新上下文(refreshContext()
  • 核心处理阶段
    1. 自动配置(AutoConfiguration)
      • 通过 @EnableAutoConfiguration 触发自动配置机制。
      • META-INF/spring.factories 加载候选自动配置类。
      • 根据条件注解(如 @ConditionalOnClass)筛选需要应用的配置。
    1. 组件扫描(Component Scan)
      • 通过 @ComponentScan 扫描并注册 @Component@Service 等注解标记的组件。
    1. Bean 定义注册
      • 注册所有 Bean 定义到 BeanFactory。
    1. 创建单例 Bean
      • 实例化并初始化所有单例 Bean(包括自动配置的组件)。
    1. 嵌入式服务器启动(如果是 Web 应用):
      • 自动配置并启动 Tomcat、Jetty 或 Undertow 等嵌入式服务器。
步骤6:刷新后的处理(afterRefresh()
  • 触发 ApplicationReadyEvent,表示应用已就绪。
  • 调用 CommandLineRunnerApplicationRunner 的实现类。

4. 关键机制详解

4.1 自动配置(AutoConfiguration)
  • 核心注解@EnableAutoConfiguration@Import(AutoConfigurationImportSelector.class)
  • 工作流程
    1. META-INF/spring.factories 加载 EnableAutoConfiguration 类对应的自动配置候选列表。
    2. 通过 @Conditional 系列注解过滤不需要的配置(如 @ConditionalOnMissingBean)。
    3. 按需配置常用组件(如 DataSource、WebMvc、Security 等)。
4.2 事件监听机制
  • 核心事件
    • ApplicationStartingEvent:启动开始(最早)。
    • ApplicationEnvironmentPreparedEvent:环境准备完成(日志初始化在此阶段)。
    • ApplicationContextInitializedEvent:上下文初始化完成。
    • ApplicationPreparedEvent:上下文准备就绪但未刷新。
    • ApplicationStartedEvent:上下文刷新完成,嵌入式服务器启动前。
    • ApplicationReadyEvent:应用完全就绪,可接受请求。
    • ApplicationFailedEvent:启动失败时触发。
4.3 外部配置加载
  • 按优先级加载配置源:
    1. 命令行参数。
    2. SPRING_APPLICATION_JSON 环境变量。
    3. application-{profile}.properties/yml
    4. application.properties/yml
    5. 默认属性(通过 SpringApplication.setDefaultProperties() 设置)。

5. 启动流程图

SpringApplication.run()
├── 创建 SpringApplication 实例
│   ├── 推断应用类型
│   ├── 加载初始化器
│   ├── 加载监听器
│   └── 推断主类
│
├── 运行应用
│   ├── 创建并配置 ApplicationEnvironment
│   ├── 触发 ApplicationEnvironmentPreparedEvent(日志初始化)
│   ├── 创建 ApplicationContext
│   ├── 准备上下文(应用初始化器)
│   ├── 刷新上下文
│   │   ├── 自动配置
│   │   ├── 组件扫描
│   │   ├── Bean 定义注册
│   │   ├── 创建单例 Bean
│   │   └── 启动嵌入式服务器(Web 应用)
│   └── 触发 ApplicationReadyEvent
│
└── 应用启动完成

6. 总结

Spring Boot 的启动流程通过事件驱动约定大于配置的原则,实现了高效、自动化的应用初始化。核心机制包括:

  • 自动配置:基于类路径和条件注解动态配置组件。
  • 事件监听:通过 ApplicationListener 响应生命周期事件。
  • 外部配置:灵活加载和合并多种配置源。

理解启动流程有助于排查问题(如自动配置未生效)、自定义初始化逻辑,以及开发 Spring Boot 扩展组件。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐