如何通过环境变量设置名称中带有下划线的 Spring Boot 属性?
Posted
技术标签:
【中文标题】如何通过环境变量设置名称中带有下划线的 Spring Boot 属性?【英文标题】:How to set a Spring Boot property with an underscore in its name via Environment Variables? 【发布时间】: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
。
【参考方案1】:
这是一个老问题,但如果其他人(如我)最终在这里寻找此信息,我会回答它。
HIBERNATE_FORMAT_SQL 应该可以解决问题
实际上,“翻译”的不是 OS 环境变量,而是 Spring 属性名称。
名称以多种方式翻译,并根据可用的环境变量进行查找。例如。 “hibernate.format.sql”查找为:
-
hibernate.format.sql(原样)
hibernate_format_sql(点替换为下划线)
hibernate_format_sql(破折号替换为下划线,在您的情况下也是如此)
hibernate_format_sql(破折号和点替换为下划线,在您的情况下相同)
然后与大写相同:
-
HIBERNATE.FORMAT.SQL(原样)
HIBERNATE_FORMAT_SQL(点替换为下划线)
HIBERNATE_FORMAT_SQL(破折号替换为下划线,再次相同)
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));
【讨论】:
以上是关于如何通过环境变量设置名称中带有下划线的 Spring Boot 属性?的主要内容,如果未能解决你的问题,请参考以下文章
PowerShell 中带括号的环境变量名称,如 %ProgramFiles(x86)%?