我已经写了类似的东西,我把一个公众封闭在一个类别,然后我MIXIN到服务:
// TimingCategory.groovy
/**
* Provides common AOP timing functionality to Services which mixin this category.
*/
class TimingCategory {
static Closure timer = { String label = "The call", Closure closure ->
Long start = System.currentTimeMillis()
def result = closure.call()
Long end = System.currentTimeMillis()
Long duration = end - start
log.warn "${label} took ${duration} ms"
return result
}
}
在其他类,你刚才提到的timer
封这样:
@Mixin(TimingCategory)
public class WhateverService {
public String doSomeWork() {
timer "Doing a lot of work", {
1000.times { doSomething() }
someMethodWithAStringReturnValue()
}
}
}
这会给你登录的输出“WARN:做了很多工作,发生在NN MS”并返回内罩为doSomeWork
方法的返回值的值。
为了您的taglib例如,只是包裹out << ...
在
timer "Writing an emoticon", {
// your code
}
代码。
如果您不关心是否通过内部返回值,则可以返回持续时间作为闭包调用的结果。
更新:
我可能会误解 - 你问如何包装的taglib执行,而无需修改代码的taglib在所有?如何创建一个自定义的标签库接受主体并将其传递给其他标签库以执行?
我没有试过,但类似:
class TimedTagLib {
static namespace = "timer"
def timedTag = { attrs, body ->
timer "Executing the timed tag", {
out << body()
}
}
}
并调用它像
<timer:timedTag><g:emoticon whatever="something">Text</g:emoticon></timer:timedTag>
更新2:
好了,我试了一下。工作正常。我的最终代码(I加入第二定时器闭合返回的持续时间):
// TimedTagLib.groovy
@Mixin(TimingCategory)
class TimedTagLib {
static namespace = "timer"
def timedTag = { attrs, body ->
def duration = returnTimer "Printing the timed tag", {
out << body()
}
out << "Took ${duration} ms to print"
}
}
和视图:
// someView.gsp
<timer:timedTag>
<g:formatLocalDate date="${LocalDate.now()}" />
</timer:timedTag>
产生的HTML是:
03/19/2013
Took 6 ms to print
而且它也写到日志。
那么'getProperty'或'missingProperty'中的切入点怎么样?不确定grails如何获得闭包属性 – Will 2013-03-19 12:51:48
也许更简单的方法是用metaClass更改闭包的行为。 – 2013-03-19 13:53:22
请向Grails Jira添加JIRA功能请求。这是Grails中缺少的一个功能。请参阅http://jira.grails.org/browse/GRAILS-6680?focusedCommentId=56175&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-56175了解更多用例(taglib缓存)。 – 2013-03-20 04:30:13