2013-03-19 66 views
4

在Grails中(至少到目前的2.2版本),taglibs是闭包。对于某些taglib关闭,我想使用一些“around”类型的建议/将封闭包装在拦截器中。闭包的方面(类似)函数

换一种方式,让我们说有这个标签库直接从Grails的文档:

class SimpleTagLib { 
    def emoticon = { attrs, body -> 
     out << body() << (attrs.happy == 'true' ? " :-)" : " :-(") 
    } 
} 

现在,无需修改标签库的代码,我想时间长的“表情符号”是如何发生到执行。

Spring AOP(和我能找到的所有其他AOP)似乎只适用于Java方法 - 而taglib总是基于闭包。一个“左右”的切入点对此来说是完美的,但我无法弄清楚如何使其工作。

+0

那么'getProperty'或'missingProperty'中的切入点怎么样?不确定grails如何获得闭包属性 – Will 2013-03-19 12:51:48

+0

也许更简单的方法是用metaClass更改闭包的行为。 – 2013-03-19 13:53:22

+0

请向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

回答

1

我已经写了类似的东西,我把一个公众封闭在一个类别,然后我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 

而且它也写到日志。