java - 使用环境变量填充 @ConfigurationProperties 中的 Map

标签 java spring spring-boot

我有这个@ConfigurationProperties:

@ConfigurationProperties(prefix = "myapp")
public class CustomProperties {

    private Map<String, String> namespace = new HashMap<>();

    public Map<String, String> getNamespace() {
        return namespace;
    }
}

在启动应用程序之前,我将这些参数作为程序参数:

--myapp.namespace.namespace1.connection="xxxx"
--myapp.namespace.namespace1.url="yyy"
--myapp.namespace.namespace2.topic="zzz"
--myapp.namespace.namespace2.id="ccc"

它工作成功,命名空间映射将包含四个条目:

{namespace2.id=ccc, namespace1.connection=xxxx, namespace2.topic=zzz, namespace1.url=yyy}

现在我正在“dockerizing”应用程序。我怎样才能让它与环境变量一起工作?我尝试过:

MYAPP_NAMESPACE_NAMESPACE1.CONNECTION="xxxx"
MYAPP_NAMESPACE_NAMESPACE1.URL="yyy"
MYAPP_NAMESPACE_NAMESPACE2.TOPIC="zzz"
MYAPP_NAMESPACE_NAMESPACE2.ID="ccc"

MYAPP_NAMESPACE_NAMESPACE1_CONNECTION="xxxx"
MYAPP_NAMESPACE_NAMESPACE1_URL="yyy"
MYAPP_NAMESPACE_NAMESPACE2_TOPIC="zzz"
MYAPP_NAMESPACE_NAMESPACE2_ID="ccc"

而且它不起作用。你能帮我吗?

谢谢费尔南多。

最佳答案

为了防止其他人使用 Kubernetes,有一种比环境变量更简单的方法可以将复杂的配置注入(inject)到 Spring Boot 应用程序中。我们可以有一个名为 application.yml 的配置映射条目,其中包含所需的配置,通过卷将该条目注入(inject)到容器中,并将环境变量 SPRING_CONFIG_ADDITIONAL_LOCATION 设置为指向该位置

步骤:

  • 创建一个名为 demo-config 的配置映射,其中包含带有 application.yml 键的多行数据
  • 从仅映射数据键 application.yml 的配置映射 demo-config 创建名为 config-volume 的卷
  • 将配置卷挂载到位于 /etc/config 的容器中
  • 将环境变量 SPRING_CONFIG_ADDITIONAL_LOCATION 设置为 /etc/config/ - 尾部斜杠是必需的
  • 应用程序启动,从 /etc/config/application.yml 读取配置并记录行 com.example.demo.AppProps - Namespace: {namespace2.id=ccc ,namespace1.connection=xxxx,namespace2.topic=zzz,namespace1.url=yyy}

测试配置类:

package com.example.demo;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

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

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "myapp")
public class AppProps {

    private Map<String, String> namespace = new HashMap<>();
    
    @PostConstruct
    public void init() {
        log.info("Namespace: {}", namespace);
    }
}

配置图:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-config
data:
  application.yml: |
    myapp:
      namespace:
        namespace1.connection: xxxx
        namespace1.url: yyy
        namespace2.topic: zzz
        namespace2.id: ccc

部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
  labels:
    app: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      volumes:
        - name: config-volume
          configMap:
            name: demo-config
            items:
              - key: application.yml
                path: application.yml
      containers:
        - name: app
          image: devatherock/demo:0.1.0-local.1
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config  
          env:
           - name: SPRING_CONFIG_ADDITIONAL_LOCATION
             value: "/etc/config/"

关于java - 使用环境变量填充 @ConfigurationProperties 中的 Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59360466/

相关文章:

java - 在 Android 的 SQlite 数据库中存储 Null

spring - 如何从 Spring 过滤器返回响应为 Json?

java - 访问在 Guice 的根对象图中不可配置的 Map<String, Interface-Impl>

java - 使用 Java 进行独立原型(prototype)设计

java - 验证 spring 上下文而不刷新它

java - XPathExpression动态返回值

java - 关于 MyBatis resultMaps 的澄清

javascript - bootstrap-year-calendar 不起作用

AWS S3 Python 客户端的 Java 等效项 "generate_presigned_post"

java - 使用 Https 和 tomcat 进行 Spring 远程处理