Spring Boot 入门、配置、自动配置与日志指南

本文聚焦 Spring Boot 的启动方式、配置管理、自动配置原理以及日志配置。内容以 Spring Boot 的“约定优于配置”和“开箱即用”能力为主,帮助你建立从“能启动项目”到“理解自动配置”的知识主线。

第一章 Spring Boot 快速入门

早期 Java Web 开发常常依赖 Servlet、JSP 和大量 XML 配置。Spring Boot 的目标是用约定大于配置的方式简化这些工作:内嵌服务器、自动装配常用组件、默认集成主流能力,让项目可以快速启动。

1.1 创建 Spring Boot 项目

通过 IDEA 的 Spring Initializr 创建项目时,通常可以先选择:

  • Java 17
  • 依赖:Spring Web
  • 按需补充:LombokMySQL DriverValidation

启动类示例:

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

启动后控制台会输出端口信息,默认是 8080。如果能正常访问 http://localhost:8080,说明应用已经成功启动。

1.2 核心注解:@SpringBootApplication

@SpringBootApplication 是一个组合注解,内部整合了 Spring Boot 启动最核心的三部分能力:

组成部分作用
@Configuration标识当前类是配置类,可以向容器注册 Bean
@EnableAutoConfiguration启用 Spring Boot 自动配置
@ComponentScan扫描当前包及其子包中的组件

需要特别注意包扫描范围:

  • @ComponentScan 默认只扫描启动类所在包及其子包
  • 如果业务类、配置类放在扫描范围之外,Spring 默认不会把它们注册到容器中。
  • 常见做法是把启动类放在根包位置,减少额外配置。

自动配置类通常不依赖业务项目自己的包扫描,而是通过 @EnableAutoConfiguration + @Import 主动导入,这是理解自动配置原理的重要前提。


第二章 配置管理与属性绑定

Spring Boot 的配置体系不仅仅是“把值写进 application.yml”。它还包括配置文件格式选择、优先级、多环境、类型绑定和校验等内容。

2.1 application.ymlapplication.properties

Spring Boot 默认支持两种主流配置文件格式:

  • application.properties
  • application.ymlapplication.yaml

properties 示例:

Properties
server.port=8080
app.name=demo-app
app.security.enabled=true

yml 示例:

YAML
server:
  port: 8080

app:
  name: demo-app
  security:
    enabled: true

两者的区别主要体现在表达方式:

  • properties 结构扁平,适合简单配置。
  • yml 层级更清晰,适合复杂对象、集合与嵌套配置。
  • 团队统一使用一种格式即可,不建议同一个项目长期混用两套主配置文件。

2.2 读取配置:@Value@ConfigurationProperties

@Value 适合读取少量、离散的单个配置项:

Java
@Component
public class AppInfo {
    @Value("${server.port}")
    private int port;

    @Value("${app.greeting:你好}")
    private String greeting;
}

@ConfigurationProperties 更适合把一组同前缀配置批量绑定到对象中:

YAML
app:
  name: 我的应用
  version: 1.0.0
Java
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }
}

使用建议:

  • 读取单值、临时值时可以用 @Value
  • 读取一组业务配置、公共配置时优先用 @ConfigurationProperties
  • 需要类型安全、配置集中管理时,更适合用 @ConfigurationProperties

2.3 配置优先级

Spring Boot 支持多种配置来源,常见优先级从低到高如下:

  1. application.yaml
  2. application.yml
  3. application.properties
  4. 环境变量,例如 SERVER_PORT=9000
  5. Java 系统属性,例如 -Dserver.port=9000
  6. 命令行参数,例如 --server.port=10010

如果同一个配置项在多个位置都出现,优先级高的会覆盖优先级低的。

补充说明:

  • application.ymlapplication.yaml 本质上是同一种 YAML 格式,只是文件扩展名不同。
  • 在同一目录、同一配置层级下,如果同时存在 application.properties 和 YAML 文件,通常以 application.properties 为准;但真实排错时更重要的是先看有没有环境变量、系统属性和命令行参数覆盖它。

2.4 多环境配置

Spring Boot 支持按环境拆分配置,常见文件有:

  • application.yml
  • application-dev.yml
  • application-test.yml
  • application-prod.yml

在主配置文件中可以指定当前激活环境:

YAML
spring:
  profiles:
    active: dev

也可以通过命令行动态指定:

Bash
java -jar app.jar --spring.profiles.active=prod

2.5 配置绑定校验

如果希望在应用启动阶段尽早发现配置错误,可以在 @ConfigurationProperties 上配合校验注解使用。

Java
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

@Validated
@Component
@ConfigurationProperties(prefix = "app.oss")
public class OssProperties {

    @NotBlank
    private String endpoint;

    @NotBlank
    private String accessKeyId;

    @NotBlank
    private String accessKeySecret;

    @NotNull
    private Integer connectTimeout;
}

2.6 松散绑定

@ConfigurationProperties 支持松散绑定,也就是配置文件中的命名风格和 Java 字段命名不需要完全一致。

例如下面几种形式,Spring Boot 都可以绑定到 accessKeyId

  • access-key-id
  • access_key_id
  • accessKeyId

因此在配置文件中更推荐使用短横线风格。


第三章 条件装配与自动配置原理

自动配置是 Spring Boot 最核心的能力之一。它解决的问题不是“能不能注册 Bean”,而是“在合适的条件下自动注册正确的 Bean”。

3.1 条件装配注解

注解条件
@ConditionalOnClass类路径中存在指定类时
@ConditionalOnMissingClass类路径中不存在指定类时
@ConditionalOnMissingBean容器中不存在指定 Bean 时
@ConditionalOnBean容器中存在指定 Bean 时
@ConditionalOnProperty配置项满足条件时
@ConditionalOnWebApplication当前应用是 Web 应用时
@ConditionalOnNotWebApplication当前应用不是 Web 应用时
@ConditionalOnSingleCandidate指定类型只有一个候选 Bean 时

示例:

Java
@Configuration
@ConditionalOnClass(name = "com.google.gson.Gson")
public class GsonAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "app.json", name = "enabled", havingValue = "true", matchIfMissing = true)
    public Gson gson() {
        return new Gson();
    }
}

3.2 什么是自动配置

自动配置指的是:当 Spring Boot 项目启动时,框架会根据当前依赖、环境和配置条件,自动选择合适的配置类并把对应 Bean 注册到 IOC 容器中。

自动配置主线可以概括为:

  1. 启动类上的 @SpringBootApplication 包含 @EnableAutoConfiguration
  2. @EnableAutoConfiguration 通过 @Import 导入自动配置选择器
  3. 选择器从约定位置读取自动配置类清单
  4. 自动配置类结合条件注解决定是否生效
  5. 生效后向容器注册 Bean

3.3 @ImportAutoConfigurationImportSelector

Text
@SpringBootApplication
  -> @EnableAutoConfiguration
    -> @Import(AutoConfigurationImportSelector.class)
      -> 读取自动配置类清单
      -> 条件过滤
      -> 导入配置类

这里的关键角色是 AutoConfigurationImportSelector。它会在运行时决定当前项目真正需要导入哪些自动配置类。

3.4 自动配置清单从哪里来

不同 Spring Boot 版本中,自动配置清单文件位置略有差异:

版本配置清单
Spring Boot 2.x 及更早META-INF/spring.factories
Spring Boot 3.xMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

3.5 starter 与 autoconfigure 的关系

概念作用
starter负责聚合一组常用依赖
autoconfigure负责根据依赖和环境自动注册 Bean

spring-boot-starter-web 为例:

  • starter 负责把 Spring MVC、Tomcat、JSON、校验等依赖带进来
  • 自动配置负责判断这些依赖是否存在,并决定是否创建相关 Bean

3.6 自定义 starter 的基本步骤

如果你要把一套公共组件封装给多个项目复用,通常会把它设计成自定义 starter。

第一步:定义属性类

Java
@ConfigurationProperties(prefix = "example.oss")
public class OssProperties {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
}

第二步:编写自动配置类

Java
@Configuration
@EnableConfigurationProperties(OssProperties.class)
@ConditionalOnClass(OssClient.class)
public class OssAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public OssClient ossClient(OssProperties properties) {
        return new OssClient(
            properties.getEndpoint(),
            properties.getAccessKeyId(),
            properties.getAccessKeySecret()
        );
    }
}

第三步:注册自动配置类

  • Spring Boot 3.x:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • Spring Boot 2.x:META-INF/spring.factories

第四步:封装 starter 依赖

  • xxx-spring-boot-starter 一般不写业务代码
  • 它通常依赖 xxx-spring-boot-autoconfigure 与对应第三方 SDK

第四章 日志管理:Logback

Spring Boot 默认使用 Logback 作为日志实现。日志配置不仅关系到调试体验,也关系到线上排障、审计和问题回溯。

4.1 默认日志与基本使用

常见日志级别从低到高如下:

Text
trace < debug < info < warn < error

代码中一般通过 LoggerFactory 获取日志对象:

Java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @GetMapping("/users")
    public String list() {
        log.info("查询用户列表");
        return "ok";
    }
}

4.2 日志配置文件

Spring Boot 支持多种日志配置方式,常见包括:

  • 直接在 application.ymlapplication.properties 中写 logging.*
  • 使用 logback-spring.xml
  • 使用 logback.xml

通常更推荐使用 logback-spring.xml

4.3 控制台日志格式

YAML
logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"

4.4 文件输出

YAML
logging:
  file:
    name: logs/app.log

或者:

YAML
logging:
  file:
    path: logs

常见建议:

  • 本地开发可以只输出到控制台
  • 测试和生产环境建议输出到文件
  • 线上最好配合日志采集系统统一收集

4.5 按包级别设置日志级别

YAML
logging:
  level:
    root: info
    com.example.controller: debug
    com.example.service: info
    org.springframework.web: warn

4.6 logback-spring.xml 示例

XML
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_PATH" value="logs" />

    <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.rolling.RollingFileAppender">
        <file>${LOG_PATH}/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <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>

本文小结

  • 理解 @SpringBootApplication 的组成与启动流程。
  • 使用 application.yml、多环境与属性绑定管理配置。
  • 理解条件装配、自动配置、starter 与 autoconfigure 的关系。
  • 根据场景配置控制台日志、文件日志与按包日志级别。