SpringBoot 获取配置文件值、获取环境变量的方式

文章目录

    • [1. 配置文件基础](#1. 配置文件基础)
    • [2. 使用 @Value 注解获取配置值](#2. 使用 @Value 注解获取配置值)
      • [2.1 基本用法](#2.1 基本用法)
      • [2.2 配置示例 (application.yml)](#2.2 配置示例 (application.yml))
    • [3. 使用 @ConfigurationProperties 批量注入](#3. 使用 @ConfigurationProperties 批量注入)
      • [3.1 创建配置类](#3.1 创建配置类)
      • [3.2 启用配置属性](#3.2 启用配置属性)
    • [4. 使用 Environment 接口](#4. 使用 Environment 接口)
    • [5. 获取环境变量](#5. 获取环境变量)
      • [5.1 直接获取系统环境变量](#5.1 直接获取系统环境变量)
      • [5.2 通过 Environment 获取环境变量](#5.2 通过 Environment 获取环境变量)
    • [6. 配置文件的 Profile 支持](#6. 配置文件的 Profile 支持)
      • [6.1 不同环境的配置文件](#6.1 不同环境的配置文件)
      • [6.2 使用 Profile 的配置类](#6.2 使用 Profile 的配置类)
    • [7. 高级用法:条件化配置](#7. 高级用法:条件化配置)
      • [7.1 使用 @ConditionalOnProperty](#7.1 使用 @ConditionalOnProperty)
    • [8. 配置验证](#8. 配置验证)
      • [8.1 添加验证注解](#8.1 添加验证注解)
    • [9. 实际应用示例](#9. 实际应用示例)
      • [9.1 完整的服务类](#9.1 完整的服务类)
    • [10. 最佳实践建议](#10. 最佳实践建议)
      • [10.1 配置命名规范](#10.1 配置命名规范)
      • [10.2 安全敏感配置](#10.2 安全敏感配置)
    • [11. 配置刷新机制](#11. 配置刷新机制)
    • 12、环境变量
    • 总结

1. 配置文件基础

Spring Boot 支持多种格式的配置文件:

  • application.properties
  • application.yml
  • application.yaml

配置文件默认加载顺序:

  1. file:./config/ (项目根目录下的config子目录)
  2. file:./ (项目根目录)
  3. classpath:/config/ (resources/config目录)
  4. classpath:/ (resources目录)

2. 使用 @Value 注解获取配置值

2.1 基本用法

java 复制代码
@Component
public class ConfigService {
    
    // 获取普通配置值
    @Value("${app.name}")
    private String appName;
    
    // 设置默认值
    @Value("${server.port:8080}")
    private int port = 8080;
    
    // 获取布尔值
    @Value("${app.enabled:true}")
    private boolean enabled;
    
    // 获取列表值
    @Value("${app.tags:java,spring}")
    private List<String> tags;
    
    // 获取数组值
    @Value("${app.servers}")
    private String[] servers;
    
    public void printConfig() {
        System.out.println("App Name: " + appName);
        System.out.println("Port: " + port);
        System.out.println("Enabled: " + enabled);
        System.out.println("Tags: " + Arrays.toString(tags.toArray()));
        System.out.println("Servers: " + Arrays.toString(servers));
    }
}

2.2 配置示例 (application.yml)

yaml 复制代码
app:
  name: MySpringBootApplication
  enabled: true
  tags: java,spring,boot
  servers: 
    - server1
    - server2
    - server3

server:
  port: 8080

3. 使用 @ConfigurationProperties 批量注入

3.1 创建配置类

java 复制代码
@ConfigurationProperties(prefix = "app")
@Component
public class AppProperties {
    
    private String name;
    private boolean enabled;
    private String version;
    private Database database;
    private List<String> features;
    private Map<String, String> properties;
    
    // 内部类定义嵌套配置
    public static class Database {
        private String url;
        private String username;
        private String password;
        private int maxConnections;
        
        // getter 和 setter 方法
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
    }
    
    // getter 和 setter 方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public boolean isEnabled() { return enabled; }
    public void setEnabled(boolean enabled) { this.enabled = enabled; }
    
    public String getVersion() { return version; }
    public void setVersion(String version) { this.version = version; }
    
    public Database getDatabase() { return database; }
    public void setDatabase(Database database) { this.database = database; }
    
    public List<String> getFeatures() { return features; }
    public void setFeatures(List<String> features) { this.features = features; }
    
    public Map<String, String> getProperties() { return properties; }
    public void setProperties(Map<String, String> properties) { this.properties = properties; }
}

3.2 启用配置属性

在主类或配置类上添加注解:

java 复制代码
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

或者在 application.yml 中配置:

yaml 复制代码
app:
  name: MyApplication
  enabled: true
  version: 1.0.0
  features:
    - feature1
    - feature2
    - feature3
  properties:
    key1: value1
    key2: value2
  database:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password
    max-connections: 100

4. 使用 Environment 接口

java 复制代码
@Service
public class EnvironmentService {
    
    @Autowired
    private Environment environment;
    
    public void getEnvironmentValues() {
        // 获取配置值
        String appName = environment.getProperty("app.name");
        String port = environment.getProperty("server.port");
        String defaultPort = environment.getProperty("server.port", "8080");
        
        // 获取特定类型的值
        Integer serverPort = environment.getProperty("server.port", Integer.class, 8080);
        Boolean debugMode = environment.getProperty("debug", Boolean.class, false);
        
        // 检查属性是否存在
        if (environment.containsProperty("app.name")) {
            System.out.println("App name exists: " + appName);
        }
        
        // 获取所有活跃的配置文件
        String[] activeProfiles = environment.getActiveProfiles();
        String[] defaultProfiles = environment.getDefaultProfiles();
        
        System.out.println("Active profiles: " + Arrays.toString(activeProfiles));
        System.out.println("Default profiles: " + Arrays.toString(defaultProfiles));
    }
}

5. 获取环境变量

5.1 直接获取系统环境变量

java 复制代码
@Component
public class SystemEnvService {
    
    public void getSystemEnvironment() {
        // 方式1:通过 System.getenv()
        String homeDir = System.getenv("HOME");
        String path = System.getenv("PATH");
        String userName = System.getenv("USER");
        
        // 方式2:通过 Environment 接口
        Environment env = new StandardEnvironment();
        String homeFromEnv = env.getProperty("HOME");
        
        // 方式3:通过 @Value 注解
        @Value("${HOME:#{null}}") // 注意:环境变量通常不以 $ 开头
        private String homePath;
        
        System.out.println("Home directory: " + homeDir);
        System.out.println("PATH: " + path);
        System.out.println("User: " + userName);
    }
}

5.2 通过 Environment 获取环境变量

java 复制代码
@Service
public class EnvVariableService {
    
    @Autowired
    private Environment environment;
    
    public void getEnvironmentVariables() {
        // 获取环境变量(注意:环境变量名通常大写)
        String dbHost = environment.getProperty("DB_HOST");
        String dbPort = environment.getProperty("DB_PORT");
        String secretKey = environment.getProperty("SECRET_KEY");
        
        // 设置默认值
        String dbHostWithDefault = environment.getProperty("DB_HOST", "localhost");
        
        System.out.println("DB Host: " + dbHost);
        System.out.println("DB Port: " + dbPort);
        System.out.println("Secret Key: " + secretKey);
    }
}

6. 配置文件的 Profile 支持

6.1 不同环境的配置文件

  • application.yml (默认配置)
  • application-dev.yml (开发环境)
  • application-test.yml (测试环境)
  • application-prod.yml (生产环境)

6.2 使用 Profile 的配置类

java 复制代码
@Configuration
@Profile("dev")
public class DevConfig {
    
    @Bean
    public String devDatabaseUrl() {
        return "jdbc:h2:mem:devdb";
    }
}

@Configuration
@Profile("!dev") // 非开发环境
public class ProdConfig {
    
    @Bean
    public String prodDatabaseUrl() {
        return "jdbc:mysql://prod-server:3306/proddb";
    }
}

7. 高级用法:条件化配置

7.1 使用 @ConditionalOnProperty

java 复制代码
@Configuration
public class ConditionalConfig {
    
    @Bean
    @ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true", matchIfMissing = false)
    public FeatureService featureService() {
        return new FeatureServiceImpl();
    }
    
    @Bean
    @ConditionalOnProperty(name = "app.cache.type", havingValue = "redis", matchIfMissing = false)
    public CacheService redisCacheService() {
        return new RedisCacheService();
    }
    
    @Bean
    @ConditionalOnProperty(name = "app.cache.type", havingValue = "memory", matchIfMissing = true)
    public CacheService memoryCacheService() {
        return new MemoryCacheService();
    }
}

8. 配置验证

8.1 添加验证注解

java 复制代码
@ConfigurationProperties(prefix = "app")
@Component
@Validated
public class ValidatedAppProperties {
    
    @NotBlank(message = "应用名称不能为空")
    private String name;
    
    @Min(value = 1, message = "端口号必须大于0")
    @Max(value = 65535, message = "端口号不能超过65535")
    private int port;
    
    @Pattern(regexp = "^\\d+\\.\\d+\\.\\d+$", message = "版本号格式不正确,应为 x.y.z 格式")
    private String version;
    
    @AssertTrue(message = "应用必须启用才能正常工作")
    private boolean enabled;
    
    // getter 和 setter 方法...
}

9. 实际应用示例

9.1 完整的服务类

java 复制代码
@Service
@Slf4j
public class ConfigurationManager {
    
    @Value("${app.name:DefaultApp}")
    private String appName;
    
    @Value("${app.version:1.0.0}")
    private String appVersion;
    
    @Autowired
    private Environment environment;
    
    @Autowired
    private AppProperties appProperties;
    
    public void displayAllConfigs() {
        log.info("=== 应用配置信息 ===");
        log.info("App Name: {}", appName);
        log.info("App Version: {}", appVersion);
        
        log.info("=== 通过 Environment 获取 ===");
        log.info("Server Port: {}", environment.getProperty("server.port"));
        log.info("Active Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
        
        log.info("=== 通过 @ConfigurationProperties 获取 ===");
        log.info("App Properties Name: {}", appProperties.getName());
        log.info("App Properties Enabled: {}", appProperties.isEnabled());
        log.info("Database URL: {}", appProperties.getDatabase().getUrl());
        
        log.info("=== 环境变量示例 ===");
        log.info("JAVA_HOME: {}", System.getenv("JAVA_HOME"));
        log.info("OS: {}", System.getProperty("os.name"));
    }
    
    public String getProperty(String key) {
        return environment.getProperty(key);
    }
    
    public String getProperty(String key, String defaultValue) {
        return environment.getProperty(key, defaultValue);
    }
    
    public <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
        return environment.getProperty(key, targetType, defaultValue);
    }
}

10. 最佳实践建议

10.1 配置命名规范

yaml 复制代码
# 推荐的命名方式
my-app:
  service:
    timeout: 30s
    retry-count: 3
  database:
    connection-timeout: 20s
    pool-size: 10

# 避免驼峰命名(虽然也支持)
myAppServiceTimeout: 30s

10.2 安全敏感配置

java 复制代码
// 对于密码等敏感信息,建议使用配置解密
@ConfigurationProperties(prefix = "app.security")
@Component
public class SecurityProperties {
    
    private String encryptedPassword;
    
    // 不直接暴露密码字段,而是提供解密方法
    public String getDecryptedPassword() {
        // 实现解密逻辑
        return decrypt(encryptedPassword);
    }
    
    private String decrypt(String encryptedValue) {
        // 解密实现
        return encryptedValue; // 简化示例
    }
}

11. 配置刷新机制

对于需要动态刷新的配置,可以结合 Spring Cloud Config 或使用 @RefreshScope

java 复制代码
@RestController
@RefreshScope
public class ConfigController {
    
    @Value("${app.message:Hello Default}")
    private String message;
    
    @GetMapping("/message")
    public String getMessage() {
        return message;
    }
}

12、环境变量

程序启动时的命令行参数

  • java设置方式
shell 复制代码
java -jar app.jar --jasypt.encryptor.password=salt
  • IDEA设置方式

  • 读取方式

shell 复制代码
System.getenv(jasypt.encryptor.password);

程序启动时的应用环境变量

  • java启动设置方式
shell 复制代码
java -jar app.jar -Djasypt.encryptor.password=salt
  • IDEA设置方式

  • 读取方式

shell 复制代码
System.getProperty(jasypt.encryptor.password);

总结

Spring Boot 提供了多种灵活的方式来获取配置值和环境变量:

  1. @Value: 适用于简单的单个值注入
  2. @ConfigurationProperties: 适用于复杂对象的批量配置
  3. Environment: 适用于程序化访问配置值
  4. Profile: 适用于不同环境的差异化配置
  5. 条件化配置: 适用于基于条件的配置加载
相关推荐
wu8587734571 小时前
Java AI Harness 落地:拥抱框架还是回归本质?深度解析选型之道
java·人工智能·回归
凤山老林1 小时前
Spring Boot 集成国产开源图库 HugeGraph 实现图谱分析的技术方案
spring boot·后端·开源·hugegraph·图谱分析
空中海1 小时前
Nacos3: 面试题库
java·面试·职场和发展
摇滚侠1 小时前
sqlplus “/ as sysdba“ 什么意思
java·数据库·oracle
神奇小汤圆1 小时前
Java基础+SQL基础 → Spring Boot实战
后端
ReSearch1 小时前
如果Go能采用混合模式,确实会比Rust更优秀
后端
user_lwl1 小时前
解决langchain4j+deepseek使用过程中reasoning_contect报错并适配DeepSeekV4
java·后端
贾铭1 小时前
如何实现一个网页版的剪映(五)如何跳转到视频某一帧
前端·后端
南方的耳朵1 小时前
VXLAN-EVPN 多租户私有网络测试文档
后端