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

时间:2014-02-11 08:20:15

标签: groovy gradle

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}

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

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

def ext(data) {
    println data.springVersion
}

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}

但运行该代码 发生以下错误。

groovy.lang.MissingPropertyException: No such property: springVersion for class: Test

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

2 个答案:

答案 0 :(得分:58)

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

答案 1 :(得分:7)

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

在代码中:

ext {
    springVersion = "3.1.0.RELEASE"
    emailNotification = "build@master.org"
}

不传递给功能"分机"具有springVersion和emailNotification属性的对象。花括号不是指POJO而是封闭。 这就是" ext"功能抱怨它无法进入房产。

传递这样一个闭包的想法,即配置闭包,接收函数将是:

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

  2. 执行closure()

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

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

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

    希望这可以帮助。 Groovy闭包花了一些时间习惯......