2015-01-26 56 views
2

我想用ENV设置覆盖application.properties中的任何属性。在我的应用程序中,我使用DOT“”前缀“来定义属性。”和后缀“破折号”(例如“ - ”)。Spring Boot:如何在Linux ENV .profile上用短划线“ - ”覆盖属性?

例如:

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 

二(失败),

Windows ENV >> APPLICATION_SERVER_JGROUPSPORT = 5445 

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

三(THIS WORKS!),

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")

+0

它看起来像org.springframework.core.env.Sy stemEnvironmentPropertySource是我需要做一些工作的地方...就像不知何故,支持 – Jason 2015-01-27 22:49:20

回答

0

这是我如何解决这个问题。

  1. I子类,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; 
    } 

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

} 
0

它直接是不可能的,但你可以使用env程序。看到这个回应https://unix.stackexchange.com/a/23714

+1

嗨 - 对不起,让我更具体。我不想在Linux ENV vars中允许破折号的方法。相反,我正在通过Spring寻找一种解决方案,它将有效的Linux ENV变量转换为Spring属性覆盖 - 即使Spring属性中有一个破折号“ - ”。 – Jason 2015-01-27 16:34:38

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

+0

SPRING_APPLICATION_JSON是相当新近的补充。你可能需要更新你的Spring Boot Parent才能使它工作。 – 2016-06-28 08:54:35

+0

诚然,它是1.3.x版本的一部分。 – jebeaudet 2016-07-05 15:20:57