5

我熟悉像这些正常的常规闭包

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正在传递,那么有效载荷在哪里?

有人可以详细解释一下这个片段吗?

4

2 回答 2

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

我希望我能够传达您想了解的内容。:)

于 2013-06-12T19:51:58.237 回答
0

此处发布的以下片段概述了用于将闭包传递给方法的几个选项。

有两个参数的方法。最后一个参数是一个闭包。

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'
// }
于 2017-01-16T15:02:08.080 回答