ext和代码块在gradle文件中的含义

uui*_*ode 40 groovy gradle

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是build.gradle的片段

我理解用{}闭包参数调用ext方法.这是正确的?所以我认为gradle正在访问springVersion和emailNotification.我将用下面的代码验证我的假设

def ext(data) {
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}
Run Code Online (Sandbox Code Playgroud)

但运行下面的代码错误发生.

groovy.lang.MissingPropertyException: No such property: springVersion for class: Test
Run Code Online (Sandbox Code Playgroud)

你具体解释ext和代码块吗?

Pet*_*ser 64

ext被简写project.ext,并且用于定义额外的属性project对象.(也可以为许多其他对象定义额外的属性.)当读取额外的属性时,ext.省略(例如println project.springVersionprintln springVersion).同样在方法中起作用.声明一个名为的方法是没有意义的ext.


Ron*_*nen 8

以下是对问题中的示例代码产生错误的原因的解释.

在代码中:

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}
Run Code Online (Sandbox Code Playgroud)

不传递函数"ext"具有springVersion和emailNotification属性的对象.花括号不是指POJO而是闭包.这就是"ext"函数抱怨它无法访问属性的原因.

通过这种闭包(称为配置闭包)的想法是接收函数将:

  1. 修改闭包的delegate属性以指向闭包属性/方法应该作用的对象.

  2. 执行闭包()

因此,闭包执行,当它引用方法/属性时,这些将在要配置的对象上执行.

因此,对您的代码进行以下修改将使其工作:

class DataObject {
   String springVersion;
   String emailNotification;
}

def ext(closure) {  
    def data = new DataObject() // This is the object to configure.
    closure.delegate = data;
    // need this resolve strategy for properties or they just get
    // created in the closure instead of being delegated to the object
    // to be configured. For methods you don't need this as the default
    // strategy is usually fine.
    closure.resolveStrategy = Closure.DELEGATE_FIRST 
    closure() // execute the configuration closure
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}
Run Code Online (Sandbox Code Playgroud)

希望这有帮助.Groovy闭包得到一些时间习惯...