【问题标题】:How to set a Spring Boot property with an underscore in its name via Environment Variables?如何通过环境变量设置名称中带有下划线的 Spring Boot 属性?
【发布时间】:2016-03-14 17:04:03
【问题描述】:

我想在 Spring Boot 应用程序中设置 hibernate.format_sql。我想使用环境变量来设置它。

Spring Boot 可以轻松地将所有环境变量从例如 FOO_BAR_BAZ 转换为 Spring 上下文中称为 foo.bar.baz 的属性。

如何在 Spring Boot 中使用环境变量设置目标名称中带有下划线的属性?大概HIBERNATE_FORMAT_SQL会被翻译成hibernate.format.sql

【问题讨论】:

  • hibernate 的属性名称无关紧要,重要的是您用来检索它的名称(为什么要保持它们相同?)。只需给它起一个无论 _ 或 . 都可以使用的名称。
  • “你为什么让它们保持不变?”:因为他要设置Hibernate属性。
  • 没关系。您可以在您的环境中将属性命名为 foo,然后仍然为休眠设置 hibernate.format_sql 属性。它们不需要相同。
  • foo 就是一个例子。我不想设置一个名为foo 的属性。我想使用环境变量设置hibernate.format_sql

标签: java spring spring-boot


【解决方案1】:

这是一个老问题,但如果其他人(如我)最终在这里寻找此信息,我会回答它。

HIBERNATE_FORMAT_SQL 应该可以解决问题

实际上“翻译”的不是 OS 环境变量,而是 Spring 属性名称。

名称以多种方式翻译,并根据可用的环境变量进行查找。例如。 “hibernate.format.sql”查找为:

  1. hibernate.format.sql(原样)
  2. hibernate_format_sql(点替换为下划线)
  3. hibernate_format_sql(破折号替换为下划线,在您的情况下也是如此)
  4. hibernate_format_sql(破折号和点替换为下划线,在您的情况下相同)

然后与大写相同:

  1. HIBERNATE.FORMAT.SQL(原样)
  2. HIBERNATE_FORMAT_SQL(点替换为下划线)
  3. HIBERNATE_FORMAT_SQL(破折号替换为下划线,再次相同)
  4. HIBERNATE_FORMAT_SQL(破折号和点替换为下划线,再次相同)

虽然您不能使用 set 或 export 命令设置名称中带有点的环境变量,但是可以使用 env 命令。我推迟判断这是否是一个好主意:

env "my.dotted.name=\"a value\"" the-command-you-want-to-run

看看SystemEnvironmentPropertySource.java 详情。我链接到特定版本,但您应该确保查看您使用的版本。

要在生产环境中解决此类问题,您可以尝试为属性解析代码打开调试日志记录:

logging:
  level:
    org.springframework.core.env: DEBUG

...或通过设置适当的环境变量:)

编辑: 我强烈建议您熟悉相关的 Spring Boot 文档主题: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config

这里的 cmets 中更棘手的示例,例如spring.jpa.properties.hibernate.criteria.literal_handling_mode,根据您启动应用程序的方式,可能会有不同的解决方案。

您可以将变量设置为 JSON,嵌入到环境变量中。

env SPRING_APPLICATION_JSON='{"spring":{"jpa":{"properties":{"hibernate":{"criteria":{"literal_handling_mode":"BIND"}}}}}}' ./gradlew bootRun

按原样设置变量也可能有效:

env spring.jpa.properties.hibernate.criteria.literal_handling_mode=BIND ./gradlew bootRun

只要我能够以这种方式在正在运行的 Spring Boot 应用程序中获取值,以上两种方法都适用于我的设置:

@Value("${spring.jpa.properties.hibernate.criteria.literal_handling_mode}")
private String testSettingThroughEnvVariable;

希望这会有所帮助! YMMV

【讨论】:

  • 属性名称中的大小写无关紧要 - 整个名称只是大写。
  • 我想通过 ENV 参数设置 spring.jpa.properties.hibernate.criteria.literal_handling_mode=BIND,但它不起作用。当我在整个 ENV 设置中使用下划线时,它们在到达服务时变成点(当然,它们在休眠时没有被正确拾取)
  • 我们对 spring.jpa.properties.hibernate.globally_quoted_identifiers 有同样的问题。我最终在 SpringApplicationBuilder 上直接用 Java 设置它。虽然它可以用于该属性,但它不适用于其他属性。 @hecko84 你找到解决问题的方法了吗?
  • @Marceau,抱歉,没有解决方案可以用 ENV 设置覆盖它。我现在将它设置在与 docker 映像中的 jar 捆绑在一起的 application.properties 中。最后,对于这个参数,这样就可以了,因为无论如何应该没有理由要覆盖它。此外,通过这种方式,我们可以防止我们的 OP 人员弄乱服务:D
  • 这不能回答问题。问题是关于hibernate.format_sql,但由于某种原因,这个答案假定hibernate.format.sql
【解决方案2】:

原来SPRING_JPA_SHOW_SQL=true 工作得很好。我不知道这是否意味着该特定属性的名称被重载,或者 Spring 是否正在做一些更聪明的事情。它解决了我的问题,并为我询问的示例提供了所需的行为。

【讨论】:

    【解决方案3】:

    我有同样的问题,环境变量spring_jpa_properties_hibernate_default_schema Spring 翻译为spring.jpa.properties.hibernate.default.schema 但Hibernate 需要hibernate.default_schema

    出于某些原因(devops 问题),我无法将其更改为 spring.jpa.properties.hibernate.default_schema - 它可以在本地机器上运行。

    我是这样解决的

    @Component
    public class HibernateConfig implements HibernatePropertiesCustomizer {
    
        private final static String HIBERNATE_CUSTOM_DEFAULT_SCHEMA_PARAM = "hibernate.default.schema";
    
        @Override
        public void customize(Map<String, Object> hibernateProperties) {
            if (hibernateProperties.containsKey(HIBERNATE_CUSTOM_DEFAULT_SCHEMA_PARAM)) {
                hibernateProperties.put(AvailableSettings.DEFAULT_SCHEMA, hibernateProperties.get(HIBERNATE_CUSTOM_DEFAULT_SCHEMA_PARAM));
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 2020-06-09
      • 2021-02-09
      相关资源
      最近更新 更多