当前位置: 首页 > 知识库问答 >
问题:

Spring Boot配置中列表的环境变量

章高朗
2023-03-14

对于我的Spring Boot应用程序,我试图使用一个环境变量来保存application.yml中的properties.topics列表(请参见下面的配置)。

properties:
      topics:
        - topic-01
        - topic-02
        - topic-03

我使用配置文件来填充properties bean(参见本spring文档),如下所示

import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("properties")
public class ApplicationProperties {
  private List<String> topics = new ArrayList<>();
  public void setTopics(List<String> topics) {
     this.topics = topics;
  }
  public List<String> getTopics() {
     return this.topics;
  }
}

通过使用环境变量,我可以在不更改应用程序.yml的情况下更改列表的内容。然而,到目前为止,我所能找到的所有示例都只适用于环境变量只包含单个值,而不是我的示例中的值集合的情况。

编辑:

为了在@vancleff的评论之后澄清,我不需要将环境变量的值保存到application.yml

另一编辑:

我认为过分简化我的问题,是搬起石头砸自己的脚。@lppEdd答案与我的问题中给出的示例配合得很好。然而,如果我需要一个更复杂的结构,而不是简单字符串主题名称的集合,会发生什么。例如,类似的东西

properties:
  topics:
    - 
      name: topic-01
      id: id-1
    - 
      name: topic-02
      id: id-2
    - 
      name: topic-03
      id: id-3

共有3个答案

越雨泽
2023-03-14
Also facing the same issue , fixed with having a array in deployment.yaml from values.yml replacing the default values of application.yml

example as : 

deployment.yml -

----------------

env: 
            - name : SUBSCRIBTION_SITES_0_DATAPROVIDER
              value: {{ (index .Values.subscription.sites 0).dataprovider | quote }}
            - name: SUBSCRIBTION_SITES_0_NAME
              value: {{ (index .Values.subscription.sites 0).name | quote }}

values.yml -

---------------

  subscription:
    sites:
      - dataprovider: abc
        name: static

application.yml -

------------------

  subscription:
    sites:
      - dataprovider: ${SUBSCRIBTION_SITES_0_DATAPROVIDER:abcd}
        name: ${SUBSCRIBTION_SITES_0_NAME:static}
    
Java Code :

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "subscription")
public class DetailsProperties {

    private List<DetailsDto> sites;

    DetailsProperties() {
        this.sites = new ArrayList<>();
    }

}

Pojo mapped :

@Getter
@Setter
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DetailsDto {
    private String dataprovider;
    private String name;
}
夏昊
2023-03-14

建议,不要过于复杂。

假设您希望将该列表作为环境变量。你可以使用

-Dtopics=topic-01,topic-02,topic-03

然后,您可以使用注入的环境Bean恢复它,并创建一个新的列表

@Bean
@Qualifier("topics")
List<String> topics(final Environment environment) {
    final var topics = environment.getProperty("topics", "");
    return Arrays.asList(topics.split(","));
}

从现在起,<<代码>清单>代码>可以是<代码> @ AutoWords。
。您也可以考虑创建自定义限定符注释,也许<代码> @主题< /代码>。

然后

@Service
class TopicService {
   @Topics
   @Autowired
   private List<String> topics;

   ...
}

甚至

@Service
class TopicService {
   private final List<String> topics;

   TopicService(@Topics final List<String> topics) {
      this.topics = topics;
   }

   ...
}

您可以做的是使用一个外部化的文件。
将该文件的路径传递给环境参数。

-DtopicsPath=C:/whatever/path/file.json

然后使用环境Bean来恢复该路径。读取文件内容并要求Jackson对其进行反序列化

您还需要创建一个简单的Topic

public class Topic {
    public String name;
    public String id;
}

它表示此JSON数组的一个元素

[
    {
        "name": "topic-1",
        "id": "id-1"
    },
    {
        "name": "topic-2",
        "id": "id-2"
    }
]
@Bean
List<Topic> topics(
        final Environment environment,
        final ObjectMapper objectMapper) throws IOException {
    // Get the file path
    final var topicsPath = environment.getProperty("topicsPath");

    if (topicsPath == null) {
        return Collections.emptyList();
    }

    // Read the file content
    final var json = Files.readString(Paths.get(topicsPath));

    // Convert the JSON to Java objects
    final var topics = objectMapper.readValue(json, Topic[].class);
    return Arrays.asList(topics);
}

晏炳
2023-03-14

节目有点晚了,但我也面临着同样的问题,这解决了它

https://github.com/spring-projects/spring-boot/wiki/Relaxed-Binding-2.0#lists-1

MY_FOO_1_ = my.foo[1]

MY_FOO_1_BAR = my.foo[1].bar

MY_FOO_1_2_ = my.foo[1][2]`

因此,以问题中的例子为例:

properties:
  topics:
    - 
      name: topic-01
      id: id-1
    - 
      name: topic-02
      id: id-2
    - 
      name: topic-03
      id: id-3

环境变量应如下所示:

PROPERTIES_TOPICS_0_NAME=topic-01
PROPERTIES_TOPICS_0_ID=id-01
PROPERTIES_TOPICS_1_NAME=topic-02
PROPERTIES_TOPICS_1_ID=id-02
PROPERTIES_TOPICS_2_NAME=topic-03
PROPERTIES_TOPICS_2_ID=id-03
 类似资料:
  • 本文向大家介绍SpringBoot+docker环境变量配置详解,包括了SpringBoot+docker环境变量配置详解的使用技巧和注意事项,需要的朋友参考一下 项目中遇到springBoot+docker需要配置不同环境变量的问题,做个简单的总结: 1.开发环境ide中启动项目 可以通过ide的环境变量参数配置,启动之后使用哪个配置,比如 这样就使用application-test.yml中的

  • 问题内容: 我正在通过Docker映像运行Jenkins。 我希望我的Jenkins安装程序提供一些预先配置的环境变量。 有什么方法可以复制一些环境变量,以便在启动詹金斯时,这些变量应该与这些预先配置的环境变量一起提供? TIA。 问题答案: 可用环境变量的列表位于此处:https : //hub.docker.com/_/jenkins/ 更新资料 如果要添加自己的环境变量,则需要构建自己的je

  • 本文向大家介绍springboot 多环境配置教程,包括了springboot 多环境配置教程的使用技巧和注意事项,需要的朋友参考一下 在上一课中我们通过idea工具没有做任何配置就构建了一个springboot项目,并且已经成功启动了,但我们都很清楚这些都远远不能达到我们实际项目的需求,比如我们要引入我们自己的redis配置、mysql配置等,应该如何处理呢?在spring mvc中我们都是通过

  • 如果不配置环境变量,每次登录 MySQL 服务器时就必须进入到 MySQL 的 bin 目录下,也就是输入“cd C:\Program Files\MySQL\MySQL Server 5.7\bin”命令后,才能使用 MySQL 等其它命令工具,这样比较麻烦。配置环境变量以后就可以在任意位置执行 MySQL 命令了,本节主要介绍怎样手动配置环境变量。 MySQL 如果不配置环境变量就只能在 my

  • 类型: Object Nuxt.js 让你可以配置在客户端和服务端共享的环境变量。 例如 (nuxt.config.js): module.exports = { env: { baseUrl: process.env.BASE_URL || 'http://localhost:3000' } } 以上配置我们创建了一个 baseUrl 环境变量,如果应用设定了 BASE_URL

  • 在SpringBoot中读取环境变量的最佳方法是什么? 在Java中,我使用了以下方法: 是否可以使用注释来实现?