基于环境变量加载不同Groovy初始化脚本的运行问题
Groovy根据环境加载配置脚本后无法访问属性的解决方法
你尝试通过环境变量加载不同的配置脚本,但运行时无法访问配置里的somename和v属性,核心原因是配置脚本里的变量是局部变量,不是脚本类的成员属性,newInstance()创建的实例无法访问局部变量。以下是三种可行的解决方案:
方案1:让配置脚本返回配置Map(最简单)
修改sets.dev.groovy,直接返回包含所有配置的Map:
[ somename: 'abc', v: [ set1: [name:"Jerry", age: 42, city: "New York", hobby:"Singing"], set2: [name:"Jerry", age: 42, city: "New York", hobby:"Singing"], ] ]
主脚本main.groovy直接使用返回的Map:
def stage = System.getenv('STAGE') ?: 'dev' // 从环境变量获取,默认dev def config = evaluate(new File("sets.${stage}.groovy")) println config.somename // 输出abc println config.v.set2.city // 输出New York
原理:evaluate执行脚本后直接拿到返回的Map,无需实例化,直接访问键值对。
方案2:用@Field注解把局部变量转为类成员
修改sets.dev.groovy,用@Field注解声明变量,让它们成为脚本类的成员属性:
import groovy.transform.Field @Field def somename = 'abc' @Field def v = [ set1: [name:"Jerry", age: 42, city: "New York", hobby:"Singing"], set2: [name:"Jerry", age: 42, city: "New York", hobby:"Singing"], ]
主脚本main.groovy可以正常实例化访问:
def stage = System.getenv('STAGE') ?: 'dev' def configClass = evaluate(new File("sets.${stage}.groovy")) def config = configClass.newInstance() println config.somename // 输出abc println config.v.set2.city // 输出New York
原理:@Field注解会让Groovy把局部变量提升为脚本类的成员变量,实例化后就能直接访问。
方案3:通过Binding共享脚本变量
主脚本main.groovy创建Binding,让配置脚本在该Binding中执行,直接共享变量:
def stage = System.getenv('STAGE') ?: 'dev' def binding = new Binding() new GroovyShell(binding).evaluate(new File("sets.${stage}.groovy")) println binding.variables.somename // 输出abc println binding.variables.v.set2.city // 输出New York // 或者直接访问绑定里的变量 println binding.somename
sets.dev.groovy不需要修改,保持原来的写法即可:
def somename = 'abc' def v = [ set1: [name:"Jerry", age: 42, city: "New York", hobby:"Singing"], set2: [name:"Jerry", age: 42, city: "New York", hobby:"Singing"], ]
原理:Groovy脚本执行时会把局部变量存入Binding,主脚本通过Binding就能直接获取这些变量。
内容的提问来源于stack exchange,提问作者xpt
相关产品推荐
相关产品推荐

