在spring boot中处理配置的详细指南

98 阅读5分钟

在大约8年之后,我目前正重新开始用Java+Spring进行编码。在过去的8年里,我花在编码上的时间明显减少了,因为我现在进入了领导岗位,使我不再写代码。尽管如此,我还是需要了解一定程度的编码,尤其是在Java世界,因为我发现我的大部分项目都是用这种语言,除非我熟悉编码,否则我无法有效地帮助我的团队。自从我停止编码以来,已经发生了很多变化,我正在重新学习一切。这是我将写的许多文章中的第一篇,随着我对新事物的了解,我将写下这些文章。另外,我正在建立一个应用程序,更多的是来自我个人的成果。我一般不能花一致的时间,这使我可以花更多的时间学习,而不是努力满足实际生活中客户项目的最后期限。

在这篇文章中,我将谈论如何在Spring Boot应用程序中使用外部化配置。

1.概述

我们将使用Spring Boot的默认设置来创建一些配置,并在我们的应用程序中读取这些配置。我们还将研究一种简单的键值方式来设置属性和基于YAML的配置。

我更喜欢使用YAML,从现在开始,我将只使用YAML为基础的设置。

2.初始设置

在实施过程中,我注意到我最终被要求使用spring-boot-configuration-processor依赖关系。否则,我就会得到一个错误,代码无法编译。在我的研究中,我并没有找到很多关于为什么需要这样做的原因,但是添加这个依赖关系为我解决了这个问题。

我添加的第二个依赖项是Actuator,它为我们提供了一些令人兴奋的工具。这是不必要的,但如果你想调试你的属性并找到更多的配置来工作,我建议你也添加这个:

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

3.设置配置文件

下面的代码是application.properties文件,这是你在Spring Boot中得到的默认格式:

# This is to expose all the endpoints for Actuator. use * for all ONLY in DEV
management.endpoints.web.exposure.include=*

# Custom Properties
bungie.rootPath="https://www.bungie.net/Platform"
bungie.apiKey=000999888111

以下是YAML格式的相同属性:

bungie:
  rootPath: "https://www.bungie.net/Platform"
  apiKey: 000999888111

4.创建将读取这些配置的Bean

现在我们已经创建了这些属性,在读取这些属性时,我们需要考虑两种使用情况:

  • 读取单一属性- 在这种情况下,我们可能需要创建一个需要读取一次的属性,或者不能与任何其他属性归为一类。在这种情况下,你可以使用@Value注解来读取它。
  • 读取一组属性--在我们的例子中,我们已经在 "bungie "类别下确定了两个分组的属性。这是我喜欢的创建属性的方式。我不喜欢有无主的属性,因此我们将只看到如何设置这些属性。下面的例子将显示我们创建一个Java Bean/Configuration,它将能够读取我们的属性文件并填充对象。
package io.howtoarchitect.destinyclanwars.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties("bungie")
@Getter @Setter
public class BungieClientSettings {
    private String rootPath;
    private String apiKey;
}

如果你观察上面的代码块,你会注意到一些事情:

  • 我们使用了@Configuration ,让Spring应用程序知道这是一个Bean,并且应该被初始化成这样
  • @Getter 和 是来自Lombok包,给了我们默认的Getters和Setters。这些是强制性的,因为Spring应用程序总是需要这些获取器和设置器。@Setter
  • @ConfigurationProperties 是在这里做主要技巧的注解。它将浏览我们上下文中所有可用的属性,并搜索任何已被映射为用户 "bungie "的属性。一旦找到,这个注解将映射YAML/Properties文件的值,并将它们添加到我们的字符串中。

5.消耗属性

一旦你完成这些设置,最后一步就是在我们的应用程序中读取这些属性。我们将在另一个Spring Bean/服务中读取这些属性:

package io.howtoarchitect.destinyclanwars.bungieclient;

import io.howtoarchitect.destinyclanwars.config.BungieClientSettings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class BungieClient {
    private static WebClient client;

    @Autowired
    private BungieClientSettings bungieClientSettings;

    public WebClient getDefaultClient() {
        client = WebClient.builder()
                .baseUrl(bungieClientSettings.getRootPath())
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader("X-API-KEY", bungieClientSettings.getApiKey())
                .build();

        return client;
    }
}

你会注意到,我已经把BungieClientSettings 作为一个@Autowired 依赖关系。这就在我的类中注入了Bean,当我需要访问这些属性时,我所需要做的就是bungieClientSettings.getAPIKey()bungieClientSettings.getRootPath()

结论

这就是你需要做的,将你的属性外部化。这在早期是很重要的,因为如果你不这样做,你最终会有许多分散在类中的属性,并且在多个环境中移动会变得很困难。

在接下来的几篇文章中,我们将看一下:

  1. 如何使用基于环境的配置:在我的案例中,我将有不同的密钥用于开发和生产,我将能够处理同样的问题。
  2. 使用Spring的云配置服务器,这将允许我们把配置集中到1个项目中,也能够在不部署代码的情况下交换设计(配置即代码模式)。
  3. 最后,我们将研究如何通过加密来保护其中的一些属性。例如,我的apiKeys ,需要进行确认。我在给出的样本中使用了随机值,但在我的应用中,我需要密钥是有效的,而且不能通过GITHUB repo的纯文本文件暴露。