Groovy Closure说明

Ant*_*ony 5 groovy

我很熟悉像这样的正常groovy闭包

def printSum = {a,b ->
   println a+b
}

printSum(5,7) // 12
Run Code Online (Sandbox Code Playgroud)

但是,我遇到了来自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)
}
Run Code Online (Sandbox Code Playgroud)

我知道上面是一个封闭.

它被这样使用:

    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")
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果serviceURL正在传递那么有效载荷在哪里?

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

dma*_*tro 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) 
Run Code Online (Sandbox Code Playgroud)

通过将闭包声明为 inline with ,上述内容变得更加精彩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")
            }
        }
    })
Run Code Online (Sandbox Code Playgroud)

这是不太冗长的。最后,它可以通过编写为简化并变得更加groovier

def response = withEndpointRequest(serviceURL) {
        HolidayRequest(xmlns: namespace) {
            Holiday {
                StartDate("2006-07-03")
                EndDate("2006-07-07")
            }
            Employee {
                Number("42")
                FirstName("Russ")
                LastName("Miles")
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这里需要注意的一点是,Closure payload是最后一个参数。

现在,请注意,直到按照您在 SpringWS 插件中的问题中提到的方式调用闭包 ( payload) 才会被调用。payload.call()

看一下作为方法参数的闭包

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