简体   繁体   English

使用Groovy在Java属性中进行变量扩展

[英]Using Groovy for variable expansion in Java properties

I frequently use standard Java property files for configuring my Groovy applications. 我经常使用标准的Java属性文件来配置我的Groovy应用程序。 One feature I have been missing is the ability to use variables as part of the property value so they can be expand dynamically during use. 我一直缺少的一个功能是能够将变量用作属性值的一部分,因此它们可以在使用过程中动态扩展。 I thought I could provide this functionality using the following design: 我以为我可以使用以下设计提供此功能:

  1. Use a special format to annotate the properties that should be expanded. 使用特殊格式注释应扩展的属性。 I have chosen to enclose such templates in double exclamation marks (!!). 我选择将这些模板包含在双惊叹号(!!)中。 These property values are essentially a template to be expanded with the local variables 这些属性值本质上是一个用局部变量扩展的模板
  2. Before using the properties in the application, use the groovy 'evaluate' method to expand application variables in the template 在使用应用程序中的属性之前,使用groovy'alcome'方法在模板中展开应用程序变量
  3. Re-assign the original property key to the new value before use 使用前将原始属性键重新分配给新值

So, if I have a property file config.properties with properties like: 所以,如果我有一个属性文件config.properties ,其属性如下:

version=2.3
local_lib=!!${env['GROOVY_HOME']}/${configProps.getProperty('version')}/lib!!

The local_lib property will be expanded from the GROOVY_HOME environment variable and the version property value. local_lib属性将从GROOVY_HOME环境变量和版本属性值进行扩展。

In my application, I have coded this as follows: 在我的应用程序中,我将其编码如下:

//Load the environment variables and configuration file
env=System.getenv()
configFile=new File('config.properties')
configProps= new Properties()
configProps.load(configFile.newDataInputStream())

//Replace configuration property values with their expanded equivalent
configProps.each{
  //if a property value is a template we evaluate it
  if (it.value.startsWith('!!')){
    valTemplate=it.value.replace('!!','"')
    it.value=evaluate(valTemplate)
  }
}

 //then we use the expanded property values 

This seems to work. 这似乎有效。 When I do 当我做

println configProps

I see that the value is expanded and not null 我看到该值被扩展而不是null

However, the getProperty method for the expanded property returns null. 但是,展开属性的getProperty方法返回null。

assert configProps.getProperty('local_lib')=='C:\\DEVTOOLS\\groovy-2.4.7/2.3/lib'
   |           |                       |
   |           null                    false
   [local_lib:C:\DEVTOOLS\groovy-2.4.7/2.3/lib, version:2.3]

What is causing this discrepancy? 造成这种差异的原因是什么? I would have expected to return the value shown in the property map. 我本来希望返回属性映射中显示的值。

Your local_lib value looks like a String , but it isn't. 您的local_lib值看起来像一个String ,但它不是。 It is a GString , only lazily coerced to String as needed (like when printing out the configProps map value). 它是一个GString ,只是根据需要懒惰地强制转换为String (就像打印出configProps映射值时一样)。

Thus, a little known effect of Properties.getProperty() takes effect here. 因此, Properties.getProperty()一个鲜为人知的效果在这里生效。 When the actual map value is not a String, Properties.getProperty() returns null . 当实际映射值不是String时, Properties.getProperty()返回null

So, in order to get the desired behavior, you need to coerce the GString to String before you store the value in the property map. 因此,为了获得所需的行为,在将值存储在属性映射中之前,需要将GString强制转换为String Like so: 像这样:

it.value=evaluate(valTemplate).toString()

or 要么

it.value=evaluate(valTemplate) as String

Then you should see the desired results downstream. 然后你应该在下游看到所需的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM