Skip to content

Spring Boot 配置文件详解

一、配置文件类型

支持的类型

1. application.properties
2. application.yml
3. application.yaml

优先级:properties > yml > yaml

位置(按优先级)

1. 项目根目录 /config/
2. 项目根目录 /
3. classpath:/config/
4. classpath:/
项目根目录/
├── config/
│   └── application.properties  ← 最高优先级
├── src/main/resources/
│   └── application.properties
├── application.properties      ← 第二优先级
└── pom.xml

二、Properties 语法

properties
# 基本键值对
server.port=8080
server.servlet.context-path=/api

# 对象
server.tomcat.max-threads=200

# 数组/列表
spring.datasource.hikari.maximum-pool-size=20

# Map
spring.datasource.hikari.connection-test-query=SELECT 1

# 包含特殊字符
spring.banner.charset=UTF-8

# 多行(使用反斜线)
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} \
  -%5p ${PID:- } -- [%thread] %-40.40logger{36} : %msg%n

# 环境变量
spring.datasource.url=${DB_URL:jdbc:mysql://localhost:3306/test}

# 系统属性
app.name=${project.artifactId}

三、YAML 语法

基本语法

yaml
# 缩进使用空格(不能用 Tab)
# 键值对
server:
  port: 8080
  servlet:
    context-path: /api

# 对象
person:
  name: 张三
  age: 18
  phone:
    home: 123456
    mobile: 654321

# 数组/列表
hobbies:
  - 篮球
  - 足球
  - 游泳

# 行内写法
languages: [Java, Python, Go]

# 多文档(使用 --- 分隔)
---
spring:
  profiles: dev
server:
  port: 8080
---
spring:
  profiles: prod
server:
  port: 80

复杂结构

yaml
# 数组对象
users:
  - name: 张三
    age: 18
  - name: 李四
    age: 20

# 复杂嵌套
company:
  departments:
    - name: 技术部
      employees:
        - name: 王五
          title: 架构师
        - name: 赵六
          title: 开发工程师
    - name: 财务部
      employees:
        - name: 钱七
          title: 会计

# 引用
base: &base
  created: 2024-01-01
user1:
  <<: *base  # 使用锚点引用
  name: 张三

四、多环境配置

方式一:profile 文件

application-dev.properties
application-test.properties
application-prod.properties
yaml
# application-dev.yml
spring:
  profiles:
    active: dev
  datasource:
    url: jdbc:mysql://localhost:3306/dev
    username: root
    password: dev123

# application-prod.yml
spring:
  profiles:
    active: prod
  datasource:
    url: jdbc:mysql://prod-server:3306/prod
    username: prod_user
    password: ${DB_PASSWORD}  # 从环境变量获取

方式二:多文档块

yaml
# application.yml
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080
---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80

激活 profile

bash
# 命令行
java -jar app.jar --spring.profiles.active=dev

# 环境变量
export SPRING_PROFILES_ACTIVE=dev

# IDEA
# Run Configuration -> Active Profiles: dev

include profile 数组(Spring Boot 2.4+)

yaml
# 2.4 之前的写法(已废弃)
spring:
  profiles:
    active: dev,common

# 2.4+ 的写法
spring:
  profiles:
    include:
      - common
      - dev
    group:
      dev: common,dev
      prod: common,prod

五、配置绑定

@ConfigurationProperties

java
// 方式1:@Component + @ConfigurationProperties
@Component
@ConfigurationProperties(prefix = "person")
public class PersonProperties {
    private String name;
    private int age;
    private List<String> hobbies;
    private Map<String, String> phone;
    
    // getters/setters
}

// 方式2:@ConfigurationPropertiesScan(Spring Boot 2.2+)
@SpringBootApplication
@ConfigurationPropertiesScan
public class Application { }

// 方式3:@EnableConfigurationProperties
@Configuration
@EnableConfigurationProperties(PersonProperties.class)
public class Config { }

YAML 配置

yaml
person:
  name: 张三
  age: 18
  hobbies:
    - 篮球
    - 足球
  phone:
    home: 123456
    mobile: 654321

宽松绑定(Relaxed Binding)

java
// Java 属性(驼峰)
private int maxPoolSize;

// YAML 可以用多种写法
max-pool-size: 20      # 短横线(推荐)
maxPoolSize: 20        # 驼峰
MaxPoolSize: 20        # Pascal
MAX_POOL_SIZE: 20      # 全大写下划线
yaml
# 全部等价
server:
  port: 8080
Server:
  Port: 8080
SERVER:
  PORT: 8080
serverPort: 8080

复杂类型绑定

java
@ConfigurationProperties(prefix = "server")
public class ServerProperties {
    
    private int port;
    private Servlet servlet;
    private Tomcat tomcat;
    
    public static class Servlet {
        private String contextPath = "/";
        
        // getter/setter
    }
    
    public static class Tomcat {
        private int maxThreads = 200;
        
        // getter/setter
    }
    
    // getters/setters
}
yaml
server:
  port: 8080
  servlet:
    context-path: /api
  tomcat:
    max-threads: 300

六、占位符与默认值

属性占位符

yaml
app:
  name: ${project.name:demo}  # Maven 属性
  version: ${project.version:1.0}
  description: ${app.name} is awesome

随机值

yaml
# 随机字符串
app:
  random:
    string: ${random.uuid}
    value: ${random.value}

# 随机数
server:
  port: ${random.int(1024,65535)}  # 1024-65535 之间
  id: ${random.long}

# 随机 UUID
session:
  id: ${random.uuid}

默认值

yaml
# ${name:defaultValue}
spring:
  datasource:
    url: ${DB_URL:jdbc:mysql://localhost:3306/default}
    username: ${DB_USER:root}
    password: ${DB_PASSWORD:}

七、敏感信息处理

方式一:环境变量

yaml
spring:
  datasource:
    password: ${DB_PASSWORD}  # 从环境变量读取
bash
export DB_PASSWORD=secret123
java -jar app.jar

方式二:命令行参数

bash
java -jar app.jar --spring.datasource.password=secret123

方式三:加密配置(推荐 Spring Cloud Config / Vault)

xml
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
yaml
spring:
  datasource:
    password: ENC(加密后的字符串)

jasypt:
  encryptor:
    password: ${JASYPT_PASSWORD}
    algorithm: PBEWithMD5AndDES

八、Spring Boot 内置配置

DataSource 配置

yaml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    
    # 连接池配置(hikari)
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

JPA 配置

yaml
spring:
  jpa:
    hibernate:
      ddl-auto: update  # none/validate/update/create/create-drop
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect
    open-in-view: false

MVC 配置

yaml
spring:
  mvc:
    throw-exception-if-no-handler-found: true
    static-path-pattern: /static/**
  web:
    resources:
      static-locations: classpath:/static/
      add-mappings: true

日志配置

yaml
logging:
  level:
    root: INFO
    com.example: DEBUG
    org.springframework.web: DEBUG
    org.hibernate: INFO
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/app.log
    max-size: 10MB
    max-history: 30

Actuator 配置

yaml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,beans,env
      base-path: /actuator
  endpoint:
    health:
      show-details: always
  health:
    db:
      enabled: true
    redis:
      enabled: true

九、@PropertySource

加载额外配置文件

java
@Configuration
@PropertySource(value = "classpath:custom.properties", ignoreResourceNotFound = true)
@PropertySource(value = "file:./config/external.properties", ignoreResourceNotFound = true)
public class CustomConfig {
    @Value("${custom.property:default}")
    private String customProperty;
}

加载 YAML

java
// Spring Boot 默认只加载 application.yml
// 如需加载其他 YAML 文件

@Configuration
@PropertySource(value = "classpath:custom.yml", factory = YamlPropertySourceFactory.class)
public class YamlConfig { }

// 自定义工厂
public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        Properties properties = factory.getObject();
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, properties);
    }
}

十、ConfigurationProcessor

生成元数据

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

作用

  1. 编译时生成配置元数据 META-INF/spring-configuration-metadata.json
  2. IDE 自动提示配置属性
  3. 校验配置属性
json
// target/classes/META-INF/spring-configuration-metadata.json
{
  "groups": [{
    "name": "person",
    "type": "com.example.PersonProperties"
  }],
  "properties": [{
    "name": "person.name",
    "type": "java.lang.String",
    "description": "姓名"
  }, {
    "name": "person.age",
    "type": "java.lang.Integer"
  }]
}

十一、面试高频问题

Q1: application.yml 和 application.properties 区别?

对比propertiesyml
语法key=value缩进层级
结构扁平树状
支持复杂结构
注释##

Q2: 多环境配置如何切换?

  1. 创建 application-{profile}.yml
  2. 主配置指定 spring.profiles.active=dev
  3. 运行参数 --spring.profiles.active=prod

Q3: 配置优先级?

命令行参数 > 外置 config 目录 > 外置根目录 > classpath config > classpath 根目录

Q4: @ConfigurationProperties vs @Value?

对比@ConfigurationProperties@Value
来源Spring BootSpring
绑定批量绑定单个属性
松散绑定支持支持
SpEL不支持支持
Validation支持不支持
复杂对象方便麻烦

Q5: 如何让配置不生效?

yaml
spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

十二、下一章预告

下一章我们将学习 Spring Boot 常用注解与条件装配

  • @Conditional 系列详解
  • @AutoConfigureAfter / @AutoConfigureBefore
  • @Configuration vs @Bean
  • Spring Boot 单元测试

基于 MIT 许可发布