我熟悉正常的groovy闭包,比如这些
def printSum = {a,b ->
println a+b
}
printSum(5,7) // 12
但是,我遇到了来自SpringWS插件的代码,我很难理解:
def withEndpointRequest = { url, payload ->
def writer = new StringWriter()
def request = new MarkupBuilder(writer)
payload.delegate = request
payload.call()
def webServiceTemplate = new WebServiceTemplate()
def response = webServiceTemplate.sendToEndpoint(url, writer.toString())
new XmlSlurper().parseText(response)
}
我知道上面是一个闭包。
它的使用方式如下:
def namespace = "http://www.myveryimportantcompany.com/hr/schemas"
def serviceURL = "http://localhost:8080/myapp/services"
def response = withEndpointRequest(serviceURL) {
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
}
如果传递serviceURL
那么有效载荷在哪里?
有人可以详细解释这个片段吗?
答案 0 :(得分:4)
在上面的实现中,withEndpointRequest
是一个带有两个参数的闭包。
withEndpointRequest(String serviceUrl, Closure payload)
。
当您从客户端使用withEndpointRequest
时,您实际上在做
def namespace = "http://www.myveryimportantcompany.com/hr/schemas"
def serviceURL = "http://localhost:8080/myapp/services"
def payload = {
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
}
def response = withEndpointRequest(serviceURL, payload)
通过声明与withEndpointRequest
内联的封闭,上述内容更加流畅。
以上也可以写成
def response = withEndpointRequest(serviceURL, {
//payload goes here as an inline closure as the second parameter
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
})
不那么冗长。最后,通过写作
,可以简化它并使其更加流畅def response = withEndpointRequest(serviceURL) {
HolidayRequest(xmlns: namespace) {
Holiday {
StartDate("2006-07-03")
EndDate("2006-07-07")
}
Employee {
Number("42")
FirstName("Russ")
LastName("Miles")
}
}
}
这里要注意的一点是Closure payload
是最后一个参数。
现在,请注意在调用payload
之前不会调用闭包(payload.call()
),如SpringWS插件中的问题所述。
查看Closures as Method Arguments。
我希望我能传达你想要理解的东西。 :)
答案 1 :(得分:0)
以下snipet发布了here,概述了用于将闭包传递给方法的几个选项。
带有两个参数的方法。最后一个参数是一个闭包。
def work(input, cl) {
cl(input)
}
定义一个闭包。
def assertJava = {
it == 'Java'
}
将闭包传递给方法的方法
work('Java', assertJava)
work 'Java', assertJava // No parenthesis.
work('Groovy', {
assert it == 'Groovy'
}) // Anonymous closure as argument.
work('Groovy') {
assert it == 'Groovy'
} // Last argument is closure and can be outside parenthesis.
work('Groovy')
{
assert it == 'Groovy'
} // Opening bracket on new line. If we want a code block (e.g. static initializer) instead of closure we must use ; to separate code.
work 'Groovy', {
assert it == 'Groovy'
} // Pay attention, no parenthesis, so comma is needed again!
// Does not work:
//
// Comma between argument list needed:
// work 'Groovy' {
// assert it == 'Groovy'
// }