Spring Boot:如何使用破折号覆盖属性" - "在Linux ENV .profile上?

时间:2015-01-26 21:04:19

标签: linux spring spring-boot

我想用ENV设置覆盖application.properties中的ANY属性。在我的应用程序中,我使用“前缀”和DOT来定义属性“。”和后缀“破折号”(例如“ - ”)。

例如:

application.server.jgroups-port= some port #

现在,我想从OS ENV设置中覆盖此属性。

在Windows上,当我设置此ENV属性时,这是我的结果:

首先(FAILS),

Windows ENV >> APPLICATION_SERVER_JGROUPS_PORT = 5445

environment.getProperty("application.server.jgroups-port") returns NULL

第二(FAILS),

Windows ENV >> APPLICATION_SERVER_JGROUPSPORT = 5445

environment.getProperty("application.server.jgroups-port") returns NULL

第三(这个工作!),

Windows ENV >> APPLICATION_SERVER_JGROUPS-PORT = 5445

environment.getProperty("application.server.jgroups-port") returns 5445

注意,最后一个上的“破折号”(例如“ - ”)。

YAY!我已经使用“破折号”从Windows ENV中有效地设置了属性。 Spring Boot将此ENV完美映射到应用程序属性。

但是,在Linux上,它不接受ENV中的“破折号”(例如“ - ”),因此当我使用与Windows上使用的相同方法>>时,我的.profile会爆炸。 APPLICATION_SERVER_JGROUPS-PORT = 5445.我需要做些什么才能使Linux ENV设置设置我的“application.server.jgroups-port”属性?

编辑: 看起来像org.springframework.core.env.SystemEnvironmentPropertySource是我需要做一些工作来支持Java中的虚线属性名称作为Linux ENV的地方。例如,在SystemEnvironmentPropertySource中调用getProperty("somePrefix.foo-suffix") = APPLICATION_SERVER_JGROUPS_PORT就像它有一个句点 - getProperty("somePrefix.foo.suffix")

4 个答案:

答案 0 :(得分:3)

您还可以提供名为SPRING_APPLICATION_JSON的环境变量,其中包含有效的JSON。这将允许您覆盖具有特殊字符的键。例如:

export SPRING_APPLICATION_JSON='{"application.server.jgroups-port": 8080}'

这样,您也可以覆盖yaml中定义的数组,如下所示:

foo.bar:
  - 1
  - 2
  - 3

使用:

export SPRING_APPLICATION_JSON='{"foo.bar": ["4","5","6"]}'

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config

答案 1 :(得分:0)

不可能直接,但您可以使用env程序。请参阅此回复https://unix.stackexchange.com/a/23714

答案 2 :(得分:0)

以下是我必须采取的措施来解决问题。

  1. 我继承了SystemEnvironmentPropertySource.java。
  2. 我覆盖了getProperty(name)并复制了父的'resolvePropertyName()'代码来进行修复。它是私有的,所以我不能只重写'resolvePropertyName()',这会更容易。
  3. 请参阅下面的resolvePropertyName()代码段。
  4. 我创建了一个ApplicationListener并在我的Spring Boot应用程序中注册它,以将此自定义PropertySource添加到MutablePropertySources的标准列表中。
  5. 这是变革的核心。我认为Spring应该在未来版本中添加此功能。

        private String resolvePropertyName(String name) {
            Assert.notNull(name, "Property name must not be null");
            if (containsKey(name)) {
                return name;
            }
    
            String usName = name.replace('.', '_');
            if (!name.equals(usName) && containsKey(usName)) {
                return usName;
            }
    
            String ucName = name.toUpperCase();
            if (!name.equals(ucName)) {
                if (containsKey(ucName)) {
                    return ucName;
                }
                else {
                    String usUcName = ucName.replace('.', '_');
                    if (!ucName.equals(usUcName) && containsKey(usUcName)) {
                        return usUcName;
                    }
    
                    // Jan. 27, 2015 - Jason
                    // Added this code to allow replacing a property with dashes to underscores
                    String usUcDashName = usUcName.replace("-", "_");
                    if (containsKey(usUcDashName)) {
                        return usUcDashName;
                    }
                    // end modification to support dashes
                }
            }
    
            return name;
        }
    

    JUnit展示了我需要发生的事情。最后的断言就是我最初打开的内容。

    @RunWith(BlockJUnit4ClassRunner.class)
    public class TestDashPropertySource extends TestCase{
    
        @Test
        public void testConvertBashToDash() throws Exception {
            Map<String, Object> mockBashENV = new HashMap<String, Object>();
    
            mockBashENV.put("APP_PREFIX_FOO", "foo");
            mockBashENV.put("APP_PREFIX_BAR", "bar");
            mockBashENV.put("APP_PREFIX_FOO_BAR", "foobar");
    
            SystemEnvironmentDashResolvingPropertySource ps = new SystemEnvironmentDashResolvingPropertySource("my-dash-handler",mockBashENV);
    
            Object foo = ps.getProperty("app.prefix.foo");
            assertEquals("Did not find correct value", "foo", foo);
    
            Object bar = ps.getProperty("app.prefix.bar");
            assertEquals("Did not find correct value", "bar", bar);
    
            Object foobar1 = ps.getProperty("app.prefix.foo.bar");
            assertEquals("Did not find correct value", "foobar", foobar1);
    
            Object foobar2_W_Dashes = ps.getProperty("app.prefix.foo-bar");
            assertEquals("Did not find correct value", "foobar", foobar2_W_Dashes);
        }
    
    }
    

答案 3 :(得分:0)

您的第二次尝试应该会成功。根据{{​​3}}:

<块引用>

将规范形式的属性名称转换为环境 变量名称可以遵循以下规则:

  • 用下划线 (_) 替换点 (.)。
  • 删除所有破折号 (-)。
  • 转换为大写。

我刚刚测试了一个非常相似的用例,它对我来说效果很好