让我们一起深入探讨Spring Boot的高级特性,通过具体举例一步步还原实现(2-外部化配置篇)

 目录

 1. `application.yml` 中配置属性

2. 实现调用例子

2.1. 创建配置类

2.2. 使用配置类

2.3. 创建 REST 控制器

2.4. 编写测试

2.5. 验证测试

3. 配置覆盖

3.1. 覆盖方式优先级阐述

3.2. 覆盖配置举例复现

3.2.1. 命令行参数覆盖

3.2.2. 环境变量覆盖

4. 总结


       Spring Boot 的外部化配置允许您在不同环境之间轻松切换配置而无需改动代码。常见的做法是使用 `application.properties` 或 `application.yml` 文件,同时也支持环境变量、命令行参数等多种配置方式。以下是让我们以 `application.yml` 文件作为一个外部化配置例子进行举例,并通过不同方式进行配置覆盖。

 1. `application.yml` 中配置属性

        首先,在 `src/main/resources/application.yml` 中定义配置属性。

`application.yml`

myapp:
  message: "Hello from application.yml"

2. 实现调用例子

2.1. 创建配置类

        开始,我们需要创建一个配置类来绑定配置文件的属性。

`MyConfiguration.java`

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp")
public class MyConfiguration {

    private String message;

    // standard getters and setters

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

2.2. 使用配置类

        接下来,我们在服务中使用这个配置。

`HelloService.java`

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class HelloService {

    private final MyConfiguration config;

    @Autowired
    public HelloService(MyConfiguration config) {
        this.config = config;
    }

    public String greet() {
        return config.getMessage();
    }
}

2.3. 创建 REST 控制器

        创建一个控制器来使用 `HelloService`。

`GreetingController.java`

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private final HelloService helloService;

    @Autowired
    public GreetingController(HelloService helloService) {
        this.helloService = helloService;
    }

    @GetMapping("/greet")
    public String greet() {
        return helloService.greet();
    }
}

2.4. 编写测试

        编写测试来验证配置是如何被加载的。

`GreetingControllerTest.java`

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GreetingControllerTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void greetingShouldReturnDefaultMessage() throws Exception {
        assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/greet",
                String.class)).contains("Hello from application.yml");
    }
}

2.5. 验证测试

        运行 `GreetingControllerTest` 以确保应用加载了 `application.yml` 中的配置,并返回了正确的消息。

3. 配置覆盖

3.1. 覆盖方式优先级阐述

        Spring Boot 的外部化配置系统是灵活的,并且支持多种配置方式。当通过不同的方法设置同一个属性时,Spring Boot 会根据以下优先级来决定使用哪个值:

No1. 命令行参数:比如使用 `java -jar app.jar --property.name=value` 来传递参数。

No2. 来自SPRING_APPLICATION_JSON的属性:通过环境变量或系统属性提供的嵌入在 `SPRING_APPLICATION_JSON` 中的 JSON 数据。

No3. Java系统属性(System.getProperties()):通常通过 `-Dproperty.name=value` 形式的 JVM 参数传递。

No4. **操作系统环境变量: 直接来自操作系统的环境变量。

No5. application.properties 或 application.yml 文件中的配置:
   - 位于 JAR 包外部的 `/config` 子目录中。
   - 位于 JAR 包外部的当前目录中。
   - 位于 JAR 包内部的 `/config` 包中。
   - 位于 JAR 包内部的根目录中。

No6. 在 @Configuration 注解类上使用 @PropertySource:当你使用 `@PropertySource` 注解来指定属性文件时。

No7. 通过 SpringApplication.setDefaultProperties 方法配置的默认属性: 这在你的主程序或应用启动类中通过编程的方式设置。

        这些来源按照上述顺序排序,列表上面的配置源会覆盖下面的配置源。因此,命令行参数的优先级最高,会覆盖所有其他的配置源,而通过 `SpringApplication.setDefaultProperties` 设置的属性优先级最低。需要注意的是,当使用 Spring Cloud 等其他配置服务器时,可能会引入其他配置源,这可能会改变上述顺序。

3.2. 覆盖配置举例复现

        在 Spring Boot 应用程序中,可以使用多种方法来提供外部配置,命令行参数、环境变量可以很容易地在应用程序启动时被注入,并且会覆盖 `application.properties` 或 `application.yml` 中定义的属性值。这种方式非常适用于在不同环境之间移植应用程序,例如从开发环境到测试环境,再到生产环境,因为它允许你在不更改代码的情况下调整配置。下面重点对其进行举例实现:

3.2.1. 命令行参数覆盖

        可以通过命令行参数来覆盖 `application.yml` 中的配置。例如:

java -jar myapp.jar --myapp.message="Hello from command line"

3.2.2. 环境变量覆盖

        可以设置一个环境变量来覆盖 `application.yml` 中的配置。例如:

在 UNIX/Linux 系统中

###打开你的终端或者在部署脚本中,设置环境变量 `MYAPP_MESSAGE`:

export MYAPP_MESSAGE="Hello from the environment variable"

###然后启动你的 Spring Boot 应用程序:

java -jar target/myapp-0.0.1-SNAPSHOT.jar

或者,你也可以在一行命令中设置环境变量并启动应用程序,这样设置的环境变量只会在这次执行中有效:

MYAPP_MESSAGE="Hello from the environment variable" java -jar target/myapp-0.0.1-SNAPSHOT.jar

在 Windows 系统中

###在命令提示符(cmd)中,你会使用 `set` 命令来设置环境变量:

set MYAPP_MESSAGE=Hello from the environment variable

###然后,和在 Linux 中一样,启动你的应用程序:

java -jar target/myapp-0.0.1-SNAPSHOT.jar

在 Docker 容器中

###如果你正在使用 Docker,你可以在 `docker run` 命令中使用 `-e` 选项来设置环境变量:


docker run -e MYAPP_MESSAGE="Hello from the environment variable" -p 8080:8080 myapp:latest

        在上述所有情况中,Spring Boot 会优先读取环境变量 。

4. 总结

        Spring Boot 的外部化配置功能非常强大,它支持类型安全的配置(通过 `@ConfigurationProperties`),允许您使用属性文件、YAML 文件、环境变量和命令行参数等来定义配置。

        本文中,我们展示了如何使用 `application.yml` 来外部化配置,并通过测试来验证配置的加载。我们使用 `@SpringBootTest` 来启动一个真实的应用上下文,并使用随机端口启动服务器,然后使用 `TestRestTemplate` 来调用端点并检查返回的消息。同时,我们配置覆盖的方式、优先级做了介绍及重点复现。希望能更好的帮助各位朋友们!!

  • 49
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ead_Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值