从日志看Spring启动过程

本文详细记录了Spring框架启动过程及DispatcherServlet初始化流程,包括applicationContext的加载与servletContext的启动顺序,以及控制器映射配置。
[code="java"]
信息: Initializing Spring root WebApplicationContext
15:07:33,078 INFO ContextLoader:189 - Root WebApplicationContext: initialization started
15:07:33,109 INFO XmlWebApplicationContext:411 - Refreshing org.springframework.web.context.support.XmlWebApplicationContext@18c56d: display name ; startup date [Wed Mar 02 15:07:33 CST 2011]; root of context hierarchy
15:07:33,156 INFO XmlBeanDefinitionReader:323 - Loading XML bean definitions from ServletContext resource [/WEB-INF/beans.xml]
15:07:33,390 INFO XmlBeanDefinitionReader:323 - Loading XML bean definitions from ServletContext resource [/WEB-INF/mail.xml]
15:07:33,406 INFO XmlWebApplicationContext:426 - Bean factory for application context [org.springframework.web.context.support.XmlWebApplicationContext@18c56d]: org.springframework.beans.factory.support.DefaultListableBeanFactory@15fc40c
15:07:33,500 INFO PropertyPlaceholderConfigurer:178 - Loading properties file from ServletContext resource [/WEB-INF/jdbc.properties]
15:07:33,500 INFO PropertyPlaceholderConfigurer:178 - Loading properties file from ServletContext resource [/WEB-INF/mail.properties]
15:07:33,562 INFO DefaultListableBeanFactory:414 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@15fc40c: defining beans [favoriteDao,messageDao,refCommentDao,referenceDao,refRequestDao,sequenceDao,userDao,daoSupport,facade,mailFactory,mailTask,mailTaskFactory,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,dataSource,txManager,sqlMapClient,sqlMapClientTmp,threadPool,cookieFilter,propertyConfigurer,mailSender,regMail,updateMail]; root of factory hierarchy
15:07:33,953 INFO ThreadPoolTaskExecutor:250 - Initializing ThreadPoolExecutor 'threadPool'
15:07:33,984 INFO ContextLoader:209 - Root WebApplicationContext: initialization completed in 906 ms
2011-3-2 15:07:34 org.apache.catalina.core.ApplicationContext log
[/code]



信息: Initializing Spring FrameworkServlet 'dispatcher'
15:07:34,015 INFO DispatcherServlet:277 - FrameworkServlet 'dispatcher': initialization started
15:07:34,015 INFO XmlWebApplicationContext:411 - Refreshing org.springframework.web.context.support.XmlWebApplicationContext@16477d9: display name [WebApplicationContext for namespace 'dispatcher-servlet']; startup date [Wed Mar 02 15:07:34 CST 2011]; parent: org.springframework.web.context.support.XmlWebApplicationContext@18c56d
15:07:34,015 INFO XmlBeanDefinitionReader:323 - Loading XML bean definitions from ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
15:07:34,046 INFO XmlWebApplicationContext:426 - Bean factory for application context [org.springframework.web.context.support.XmlWebApplicationContext@16477d9]: org.springframework.beans.factory.support.DefaultListableBeanFactory@c063ad
15:07:34,062 INFO DefaultListableBeanFactory:414 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@c063ad: defining beans [checkcodeController,userController,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,velocityConfig,viewResolver,multipartResolver]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@15fc40c
15:07:34,093 INFO VelocityConfigurer:222 - Loading Velocity config from [ServletContext resource [/WEB-INF/velocity.properties]]
15:07:34,109 INFO VelocityConfigurer:138 - ClasspathResourceLoader with name 'springMacro' added to configured VelocityEngine
15:07:34,375 INFO DispatcherServlet:296 - FrameworkServlet 'dispatcher': initialization completed in 360 ms
2011-3-2 15:07:34 org.apache.coyote.http11.Http11Protocol start


[color=red]注意两点:[/color]

[color=blue]1、Spring applicationContext先启动,servlet context后加载
2、dispatcher-servlet.xml中定义了控制器映射,使用Controller+RequestMapping注解映射时,相关controller组件扫描要定义在dispatcher-servlet.xml中,而非applicationContext.xml中。[/color]
<think> 我们正在讨论Spring Boot启动时的日志配置。用户的问题是关于Spring启动时(特别是Spring Boot)的日志配置。根据引用内容,我们可以总结如下: 1. Spring Boot默认使用Logback作为日志框架,通过`spring-boot-starter-logging`实现。 2. 日志配置文件可以是`logback-spring.xml`或`logback.xml`,但Spring Boot推荐使用`logback-spring.xml`,因为它支持Spring的Profile多环境配置和属性动态调整。 3. 在`application.properties`或`application.yml`中,可以通过`logging`前缀的配置项进行简单的日志配置,例如设置日志级别。 4. 如果使用自定义的日志配置文件(如`logback-spring.xml`),则`application.yml`中的`logging`配置将失效(引用[4]提到)。 现在,我们需要回答用户关于Spring启动日志配置的问题。由于Spring Boot启动过程涉及到日志系统的初始化,我们将按照以下步骤解释: ### 1. **Spring Boot启动日志系统的初始化过程** - Spring Boot在启动的最早阶段(甚至在`ApplicationContext`创建之前)就需要初始化日志系统,因为启动过程中的信息需要输出。 - 日志初始化由`SpringApplication`类中的`initialize`方法触发,具体是通过`LoggingApplicationListener`监听器来实现(注意:之前用户的问题中提到了`ConfigFileApplicationListener`,但日志配置由另一个监听器`LoggingApplicationListener`处理)。 - `LoggingApplicationListener`响应`ApplicationStartingEvent`事件(这是Spring Boot启动过程中最早的事件之一),在这个阶段初始化日志系统。 ### 2. **日志配置的加载顺序** - 首先,检查是否有自定义的日志配置文件(如`logback-spring.xml`或`logback.xml`)。如果有,则加载该文件。 - 如果没有自定义配置文件,则使用Spring Boot内置的默认日志配置(位于`org/springframework/boot/logging/logback/defaults.xml`,如引用[3]所示)。 - 同时,Spring Boot会检查`application.properties`或`application.yml`中的`logging`配置项,并将其应用到日志系统中。但是,如果存在自定义日志配置文件,则这些配置可能会被覆盖(引用[4]提到:如果使用了自定义日志配置文件,application.yml中的logging配置就会失效)。 ### 3. **如何配置启动时的日志** - **通过application.properties/yml配置**:可以设置全局日志级别、特定包的日志级别、日志输出路径等。例如: ```properties # 设置全局日志级别为INFO logging.level.root=INFO # 设置Spring Web包的日志级别为DEBUG logging.level.org.springframework.web=DEBUG # 输出日志到文件,默认路径为当前目录下的spring.log logging.file.name=myapplication.log # 或者设置日志目录,日志文件默认为spring.log logging.file.path=/var/log ``` 注意:这些配置在未使用自定义日志配置文件时生效。 - **通过自定义logback-spring.xml配置**:当需要更复杂的日志配置(如异步日志、自定义格式、多环境配置等)时,可以创建`logback-spring.xml`文件放在`src/main/resources`下。例如: ```xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 引入Spring Boot默认的日志配置 --> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <!-- 使用Spring Profile多环境配置 --> <springProfile name="dev"> <logger name="com.example" level="DEBUG" /> </springProfile> <springProfile name="prod"> <logger name="com.example" level="INFO" /> </springProfile> <!-- 控制台输出 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 文件输出 --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>logs/application.log</file> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="FILE" /> </root> </configuration> ``` 在这个配置中,我们使用了`<springProfile>`标签来根据不同的Profile(如dev, prod)设置不同的日志级别。注意,这个文件必须命名为`logback-spring.xml`(而不是`logback.xml`)才能使用Spring扩展功能(如Profile支持)。 ### 4. **启动日志的输出** - 在Spring Boot启动时,日志系统会按照配置输出到控制台(默认)和/或文件。启动过程中的日志级别通常由`logging.level.root`决定,但也可以通过配置调整。 - 在启动过程中,如果遇到日志配置错误(如无法识别的日志配置文件格式),Spring Boot会输出错误信息并回退到默认配置。 ### 5. **自定义日志配置的注意事项** - **位置和命名**:自定义日志配置文件必须放在`classpath`下(通常为`src/main/resources`),且命名为`logback-spring.xml`(推荐)或`logback.xml`。如果使用`logback.xml`,则无法使用Spring的Profile功能。 - **覆盖默认行为**:一旦使用了自定义配置文件,Spring Boot将不再使用其内置的默认配置,因此需要在该文件中定义所有需要的配置(可以引入默认配置,如上面示例中的`<include resource="org/springframework/boot/logging/logback/defaults.xml"/>`)。 - **与application.properties的冲突**:引用[4]提到,如果使用了自定义日志配置文件,那么`application.properties`中关于`logging`的配置将失效。因此,如果需要在自定义配置文件中使用动态属性(如通过`${}`占位符),可以启用`<springProperty>`标签来从Spring Environment中获取属性值。 ### 6. **在代码中使用日志** - 在Spring Boot应用中,我们使用SLF4J接口记录日志,如引用[3]中的示例: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyService { private static final Logger logger = LoggerFactory.getLogger(MyService.class); public void doSomething() { logger.info("This is an info message"); } } ``` ### 总结 Spring Boot启动时的日志配置主要通过`LoggingApplicationListener`在启动早期初始化。配置方式有两种: 1. **简单配置**:通过`application.properties/yml`中的`logging.*`属性,适用于简单场景。 2. **高级配置**:通过自定义`logback-spring.xml`文件,支持多环境、复杂日志策略等。 在自定义配置文件中,可以充分利用Logback的功能,并结合Spring的Profile实现多环境差异化配置。需要注意的是,自定义配置会覆盖`application.properties`中的`logging`配置。 §§相关问题§§ 1. 如何在Spring Boot中为不同环境(dev, test, prod)配置不同的日志级别? 2. 如何将Spring Boot应用的日志同时输出到控制台和文件,并设置文件按天滚动? 3. 如何在Spring Boot中集成其他日志框架(如Log4j2)? </think>### Spring Boot启动时的日志配置详解 Spring Boot启动时的日志配置由`LoggingApplicationListener`监听器处理,它会在应用启动的最早阶段(`ApplicationStartingEvent`事件)初始化日志系统。以下是关键配置要点和步骤: #### 一、核心配置方式 1. **基础配置(application.yml)** 在配置文件中直接设置日志级别和输出路径: ```yaml logging: level: root: INFO # 全局日志级别 org.springframework: DEBUG # 指定包日志级别 file: name: logs/app.log # 日志文件路径 pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" ``` > 此配置对简单场景足够,但无法实现复杂功能如异步日志[^2][^4]。 2. **高级配置(logback-spring.xml)** 创建`src/main/resources/logback-spring.xml`实现细粒度控制: ```xml <configuration> <!-- 引入Spring Boot默认配置 --> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!-- 多环境配置示例 --> <springProfile name="dev"> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="CONSOLE"/> </root> </springProfile> <springProfile name="prod"> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logs/prod.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>logs/prod-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>100MB</maxFileSize> </rollingPolicy> <encoder> <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="FILE"/> </root> </springProfile> </configuration> ``` > 注意:使用`logback-spring.xml`(非logback.xml)才能支持`<springProfile>`多环境配置[^4]。 #### 二、启动日志原理 1. **初始化顺序** ```mermaid graph LR A[ApplicationStartingEvent] --> B[LoggingApplicationListener] B --> C{配置文件存在?} C -->|logback-spring.xml| D[加载自定义配置] C -->|不存在| E[加载默认配置] D --> F[初始化LoggerContext] E --> F F --> G[创建Appender] G --> H[输出启动日志] ``` 2. **关键特性** - **默认日志框架**:通过`spring-boot-starter-logging`自动引入Logback[^2] - **早于Spring容器**:日志系统在`ApplicationContext`创建前初始化 - **优先级规则**: - `logback-spring.xml` > `logback.xml` > `application.yml`配置 - 自定义配置存在时,`application.yml`的`logging.*`配置失效[^4] #### 三、代码中使用日志 ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SpringBootApplication public class MyApp { // 1. 声明Logger实例 private static final Logger logger = LoggerFactory.getLogger(MyApp.class); public static void main(String[] args) { SpringApplication.run(MyApp.class, args); // 2. 输出启动日志 logger.info("====== Application Started ======"); logger.debug("Debug details: {}", someVariable); } } ``` > 输出示例: > `2023-08-15 10:30:45 [main] INFO com.example.MyApp - ====== Application Started ======`[^3] #### 四、最佳实践 1. **多环境差异化** 通过`<springProfile>`实现环境隔离: ```xml <springProfile name="!prod"> <!-- 开发环境:输出彩色控制台日志 --> </springProfile> <springProfile name="prod"> <!-- 生产环境:输出到文件+告警邮件 --> </springProfile> ``` 2. **敏感信息过滤** 添加自定义Filter屏蔽密码等敏感数据: ```xml <filter class="com.example.SensitiveDataFilter"/> ``` 3. **启动问题排查** 若启动时无日志输出: - 检查是否误删`spring-boot-starter-logging`依赖 - 确认`logback-spring.xml`没有语法错误 - 添加调试参数:`-Dlogback.debug=true` > 完整配置参考:[Spring Boot官方日志文档](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging)[^1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值