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

Jas*_*son 5 linux spring spring-boot

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

例如:

application.server.jgroups-port= some port #

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

在Windows上,当我设置此ENV属性时,结果如下:

首先(失败),

Windows ENV >> APPLICATION_SERVER_JGROUPS_PORT = 5445

environment.getProperty("application.server.jgroups-port") returns NULL
Run Code Online (Sandbox Code Playgroud)

第二(失败),

Windows ENV >> APPLICATION_SERVER_JGROUPSPORT = 5445

environment.getProperty("application.server.jgroups-port") returns NULL
Run Code Online (Sandbox Code Playgroud)

第三(这工作!),

Windows ENV >> APPLICATION_SERVER_JGROUPS-PORT = 5445

environment.getProperty("application.server.jgroups-port") returns 5445
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Jas*_*son 0

这是我必须采取的解决问题的方法。

  1. 我对 SystemEnvironmentPropertySource.java 进行了子类化。
  2. 我覆盖了 getProperty(name) 并复制了父级的“resolvePropertyName()”代码来进行修复。它是私有的,所以我不能只覆盖“resolvePropertyName()”,这样会更容易。
  3. 请参阅下面的resolvePropertyName() 代码片段。
  4. 我创建了一个 ApplicationListener 并将其注册到我的 Spring Boot 应用程序中,以将此自定义 PropertySource 添加到 MutablePropertySources 的标准列表中。

这就是变革的核心。我认为 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;
    }
Run Code Online (Sandbox Code Playgroud)

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);
    }

}
Run Code Online (Sandbox Code Playgroud)