Spring Boot中读取配置文件的5种方式汇总

在 Spring Boot 中,读取配置文件(如 application.properties/application.yml)的方式丰富且灵活,核心可分为基础注解式编程式类型安全绑定三大类,以下是主流方式的详细总结:

一、核心前提:配置文件基础

Spring Boot 默认加载 src/main/resources 下的 application.propertiesapplication.yml,也可通过 spring.config.name/spring.config.location 自定义配置文件路径。

方式1:@Value 注解(基础单个属性读取)

核心特点

最基础、轻量的方式,直接绑定单个配置项到字段/方法参数,支持简单类型转换、默认值、SpEL 表达式。

使用示例

1. 配置文件(application.yml)
yaml 复制代码
app:
  name: demo-app
  port: 8080
  desc: ${app.name}-${app.port}  # SpEL 拼接
2. 代码绑定
java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AppConfig {
    // 直接绑定单个属性
    @Value("${app.name}")
    private String appName;

    // 绑定并设置默认值(配置不存在时使用)
    @Value("${app.version:1.0.0}")
    private String appVersion;

    // 绑定 SpEL 拼接的属性
    @Value("${app.desc}")
    private String appDesc;
}

优缺点

  • ✅ 优点:简单易用,适合少量零散配置;
  • ❌ 缺点:不支持复杂对象、无类型校验、配置多时代码冗余,无法自动刷新(需结合 @RefreshScope)。

方式2:@ConfigurationProperties(类型安全绑定,推荐)

核心特点

将一组相关配置绑定到 Java 实体类,支持嵌套对象、类型校验、前缀分组,是 Spring Boot 推荐的配置绑定方式。

使用步骤

1. 配置文件(application.yml)
yaml 复制代码
app:
  name: demo-app
  port: 8080
  database:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
  servers:
    - 192.168.1.1
    - 192.168.1.2
2. 绑定实体类
java 复制代码
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;

// 前缀指定配置分组,需配合 @Component 或 @EnableConfigurationProperties 生效
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private Integer port;
    private Database database; // 嵌套对象
    private List<String> servers; // 集合

    // 嵌套类
    public static class Database {
        private String url;
        private String username;
        private String password;
        // getter/setter
    }

    // 必须提供 getter/setter(Spring 反射赋值)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    // 其他字段的 getter/setter
}
3. 启用配置(可选)

若实体类未加 @Component,需在配置类中通过 @EnableConfigurationProperties 启用:

java 复制代码
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class Config {
}

增强特性

  • 支持 JSR-380 校验(加 @Validated + 校验注解):

    java 复制代码
    @Component
    @ConfigurationProperties(prefix = "app")
    @Validated
    public class AppProperties {
        @NotBlank(message = "应用名称不能为空")
        private String name;
        // ...
    }
  • 支持配置自动刷新(结合 @RefreshScope)。

优缺点

  • ✅ 优点:类型安全、支持嵌套/集合、配置分组清晰、可校验;
  • ❌ 缺点:需编写实体类,略繁琐(但可通过 Lombok 简化)。

方式3:Environment 接口(编程式读取)

核心特点

Spring 核心环境接口,可动态读取所有配置(包括系统属性、环境变量、配置文件),支持配置占位符解析。

使用示例

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class EnvConfig {
    @Autowired
    private Environment env;

    public void getConfig() {
        // 读取单个配置
        String appName = env.getProperty("app.name");
        // 读取并指定默认值
        Integer appPort = env.getProperty("app.port", Integer.class, 8080);
        // 读取嵌套配置
        String dbUrl = env.getProperty("app.database.url");
    }
}

扩展能力

  • 支持配置文件激活:env.getActiveProfiles()(获取激活的环境,如 dev/prod);
  • 支持判断配置是否存在:env.containsProperty("app.name")

优缺点

  • ✅ 优点:灵活,支持动态读取、多环境适配,无需绑定实体类;
  • ❌ 缺点:无类型安全(需手动转换类型)、零散读取时代码冗余。

方式4:原生 Properties/yml 读取(手动加载)

核心特点

脱离 Spring 容器,手动加载配置文件(适合非 Spring 管理的代码),支持 propertiesyml 格式。

示例1:手动读取 properties 文件

java 复制代码
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ManualPropertiesReader {
    public static void main(String[] args) throws IOException {
        Properties props = new Properties();
        // 加载 classpath 下的配置文件
        try (InputStream is = ManualPropertiesReader.class.getClassLoader().getResourceAsStream("application.properties")) {
            props.load(is);
            String appName = props.getProperty("app.name");
        }
    }
}

示例2:手动读取 yml 文件(需依赖 snakeyaml)

xml 复制代码
<!-- pom.xml 引入依赖 -->
<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
</dependency>
java 复制代码
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.Map;

public class ManualYmlReader {
    public static void main(String[] args) {
        Yaml yaml = new Yaml();
        try (InputStream is = ManualYmlReader.class.getClassLoader().getResourceAsStream("application.yml")) {
            Map<String, Object> data = yaml.load(is);
            // 读取嵌套配置
            Map<String, Object> app = (Map<String, Object>) data.get("app");
            String appName = (String) app.get("name");
        }
    }
}

优缺点

  • ✅ 优点:完全脱离 Spring,灵活控制加载逻辑;
  • ❌ 缺点:需手动处理文件加载、类型转换、嵌套结构,无 Spring 自动装配能力。

方式5:@PropertySource 加载自定义配置文件

核心特点

加载非默认名称/路径的配置文件(如 custom.properties),配合 @Value@ConfigurationProperties 使用。

使用示例

1. 自定义配置文件(custom.properties)
properties 复制代码
custom.name=my-custom-app
custom.age=20
2. 加载并绑定
java 复制代码
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;

@Component
// 加载自定义 properties 文件(仅支持 properties,不直接支持 yml)
@PropertySource("classpath:custom.properties")
public class CustomConfig {
    @Value("${custom.name}")
    private String customName;
}

扩展:加载 yml 文件(需自定义工厂)

@PropertySource 原生不支持 yml,需自定义 PropertySourceFactory

java 复制代码
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.yaml.snakeyaml.Yaml;
import java.util.Map;

public class YmlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource resource) {
        Yaml yaml = new Yaml();
        Map<String, Object> data = yaml.load(resource.getInputStream());
        return new MapPropertySource(resource.getResource().getFilename(), data);
    }
}

使用:

java 复制代码
@PropertySource(value = "classpath:custom.yml", factory = YmlPropertySourceFactory.class)
@Component
public class CustomYmlConfig {
    @Value("${custom.name}")
    private String customName;
}

优缺点

  • ✅ 优点:支持加载自定义配置文件,补充默认配置;
  • ❌ 缺点:原生不支持 yml,需自定义工厂;多文件加载时需逐个声明。

各方式对比与选型建议

方式 类型安全 支持嵌套/集合 配置分组 手动加载 推荐场景
@Value 少量零散配置、简单值绑定
@ConfigurationProperties 大量相关配置、类型安全场景
Environment ✅(手动解析) 动态读取、多环境适配、编程式
原生手动加载 ✅(手动解析) 非 Spring 管理代码、自定义加载
@PropertySource 取决于绑定方式 加载自定义配置文件

选型总结

  1. 日常开发优先用 @ConfigurationProperties(类型安全、易维护);
  2. 零散简单配置用 @Value
  3. 动态读取/多环境适配用 Environment
  4. 非 Spring 代码或自定义加载逻辑用原生手动读取;
  5. 需加载自定义配置文件时结合 @PropertySource
相关推荐
ChrisitineTX1 小时前
双 11 预演:系统吞吐量跌至 0!一次由 Log4j 锁竞争引发的线程“集体猝死”
java·log4j
Q_Q19632884751 小时前
python+django/flask+vue的基于协同过滤算法的体育商品推荐系统
spring boot·python·django·flask·node.js·php
薛纪克1 小时前
Lambda Query:让微软Dataverse查询像“说话”一样简单
java·spring·microsoft·lambda·dataverse
程序员-周李斌1 小时前
CopyOnWriteArrayList 源码分析
java·开发语言·哈希算法·散列表
廋到被风吹走1 小时前
【Spring】两大核心基石 IoC和 AOP
java·spring
..过云雨1 小时前
14.【Linux系统编程】进程间通信详解(管道通信、System V共享内存、消息队列、信号量)
linux·c语言·c++·后端
明有所思1 小时前
springsecurity更换加密方式
java·spring
坚定信念,勇往无前1 小时前
springboot +mongodb游标分页,性能好。前端存储游标历史
前端·spring boot·mongodb
却话巴山夜雨时i1 小时前
295. 数据流的中位数【困难】
java·服务器·前端