自学内容网 自学内容网

Spring Boot中使用YAML配置文件

1. YAML 文件结构和语法

缩进与层次

YAML使用缩进来表示层级关系。每个层级的元素必须比它的父级多一个空格或Tab(推荐使用空格)。例如:

server:
  port: 8080
  address: localhost
列表与映射

列表用 - 开头,映射则用 key: value 形式。可以混合使用。

myapp:
  features:
    - featureA
    - featureB
  settings:
    timeout: 30s
    maxConnections: 50
多行字符串

对于较长的字符串,可以使用 |> 来表示多行文本。|会保留换行符,而>会将多行合并为一行并去掉多余的空白。

message: |
  这是一个多行字符串。
  它保留了换行符。
message2: >
  这也是一个多行字符串。
  但它的换行符被忽略了。
使用锚点和别名避免重复

为了减少冗余,YAML允许使用锚点(&)和别名(*)来引用之前定义的内容。

defaults: &defaults
  timeout: 30s
  retries: 3

service1:
  <<: *defaults
  url: http://service1.example.com

service2:
  <<: *defaults
  url: http://service2.example.com

这里,<<: *defaults 表示将 defaults 中的所有属性合并到当前节点中。

2. 多环境配置

激活特定配置文件

你可以通过命令行参数、系统属性或在代码中设置激活的配置文件。

  • 命令行:java -jar app.jar --spring.profiles.active=dev
  • 系统属性:-Dspring.profiles.active=dev
  • 应用程序内:spring.profiles.active=dev
组合配置文件

如果你有多个配置文件,比如 application.ymlapplication-dev.yml,后者会覆盖前者中的相同配置项。

3. 属性占位符和默认值

占位符引用

可以使用 ${} 语法来引用其他属性或环境变量,并可设置默认值。

database:
  url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/dbname
动态表达式

除了静态替换外,还可以使用 Spring Expression Language (SpEL) 来动态计算值。

maxThreads: '#{T(java.lang.Runtime).getRuntime().availableProcessors() * 2}'

4. 配置类与 @ConfigurationProperties

自定义配置类

创建一个POJO类用于接收配置项,并使用 @ConfigurationProperties 注解绑定到这个类。

@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
    private String name;
    private List<String> admins = new ArrayList<>();
    
    // getters and setters
}
验证配置

为了确保配置的有效性,可以在配置类上添加JSR-303/Bean Validation注解。

@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
    @NotNull
    private String name;
    
    @Size(min = 1)
    private List<String> admins = new ArrayList<>();

    // getters and setters
}

5. 使用 @Value 注解注入配置

简单注入

直接使用 @Value 注入简单的配置项。

@Component
public class MyComponent {
    private final String apiKey;

    public MyComponent(@Value("${myapp.api-key}") String apiKey) {
        this.apiKey = apiKey;
    }
}
结合 SpEL 使用

@Value 支持 SpEL 表达式,允许进行更复杂的逻辑操作。

@Value("#{${myapp.timeout} * 1000}")
private int timeoutInMillis;

SpEL不仅限于简单的数学运算,还可以执行条件判断、调用方法等复杂操作。例如:

@Value("#{T(java.lang.Math).random() > 0.5 ? 'high' : 'low'}")
private String randomLevel;
引用其他bean的方法

你可以在表达式中直接引用其他bean的方法:

@Component
public class UtilityService {
    public String generateToken() {
        return UUID.randomUUID().toString();
    }
}

@Component
public class MyComponent {
    @Value("#{@utilityService.generateToken()}")
    private String token;
}

6. 加密敏感信息

Jasypt

Jasypt 是一个流行的库,用于加密 Spring Boot 应用程序中的敏感数据。你可以在 pom.xml 中添加依赖,并使用它来加密配置项。

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

然后,在配置文件中使用 {cipher} 标签来标记加密过的值。

myapp:
  secret: ENC(encrypted_value)

要解密这些值,你需要设置 jasypt.encryptor.password 属性来指定加密密码。

jasypt:
  encryptor:
    password: my_secret_password

除了前面提到的基本用法,Jasypt还支持多种加密算法以及密钥管理策略。你可以通过配置 jasypt.encryptor.* 属性来自定义加密行为。

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    password: my_secret_password
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

此外,Jasypt也提供了对非对称加密的支持,如RSA。

7. 使用外部化配置

优先级顺序

Spring Boot 按照一定的顺序加载配置源,从命令行参数到默认配置文件。了解这些来源的加载顺序有助于正确地管理和覆盖配置。

  1. 命令行参数
  2. 来自 SPRING_APPLICATION_JSON 的属性(嵌入在环境变量或系统属性中)
  3. 操作系统的环境变量
  4. Java 系统属性 (System.getProperties())
  5. RandomValuePropertySource 配置的随机属性 (random.*)
  6. 打包在 jar 包外的应用配置文件 (application-{profile}.properties 或 .yml)
  7. 打包在 jar 包内的应用配置文件 (application-{profile}.properties 或 .yml)
  8. 配置文件(如 bootstrap.properties 或 bootstrap.yml),适用于微服务架构中的配置服务器
  9. 默认属性(通过 SpringApplication.setDefaultProperties 指定)

8. 高级特性

条件化配置

使用 @ConditionalOnProperty 注解可以根据配置属性的存在与否来有条件地加载bean。

@Bean
@ConditionalOnProperty(name = "myapp.enabled", havingValue = "true")
public MyService myService() {
    return new MyServiceImpl();
}

除了 @ConditionalOnProperty,还有其他条件注解,如 @ConditionalOnClass, @ConditionalOnMissingBean 等,可以根据类路径上的类、是否存在某些bean等条件来决定是否加载配置。

@Bean
@ConditionalOnClass(name = "com.example.MyLibraryClass")
public MyService myService() {
    return new MyServiceImpl();
}
使用 EnvironmentPostProcessor 扩展配置处理

为了在应用程序启动前修改环境变量,你可以实现 EnvironmentPostProcessor 接口。例如,根据系统属性动态调整配置文件的位置:

public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        String customConfigLocation = System.getProperty("custom.config.location");
        if (customConfigLocation != null) {
            environment.getPropertySources().addFirst(new ResourcePropertySource(customConfigLocation));
        }
    }
}

然后注册这个处理器:

spring.application.additional-spring-configuration-metadata=classpath:META-INF/spring-configuration-metadata.json

并且在 META-INF/spring.factories 中声明:

org.springframework.boot.env.EnvironmentPostProcessor=com.example.CustomEnvironmentPostProcessor
配置元数据支持

为了提高开发体验,Spring Boot 提供了对配置元数据的支持,使得IDE能够更好地理解你的配置选项,并提供自动完成等功能。这需要在项目中包含 spring-boot-configuration-processor 依赖。

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


原文地址:https://blog.csdn.net/m0_50742275/article/details/144330498

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!