grails – 闭包的Aspect(类似)函数

在Grails中(至少到当前版本2.2),taglibs是闭包.对于某些taglib闭包,我想在拦截器中使用一些“around”类型的建议/封装闭包.

换句话说,让我们说直接来自Grails doc的这个taglib:

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

现在,在不修改taglib代码的情况下,我想知道“表情符号”执行需要多长时间.

Spring AOP(以及我能找到的所有其他AOP)似乎只适用于Java方法 – 而taglibs总是基于闭包.一个“周围”的切入点对于这个来说是完美的,但我无法弄清楚如何让它发挥作用.

解决方法

我写了类似的东西,我把它作为一个公共关闭在一个类别然后混合到服务:

// 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
    }
}

在其他类中,您只需引用计时器闭包:

@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执行?如何创建一个自定义taglib,它接受正文并将其传递给其他taglibs执行?

我没试过这个,但是有点像:

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:

好的,我试过了.工作良好.我的最终代码(我添加了第二个定时器闭包,它返回持续时间):

// 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

它还写入了日志.

相关文章

背景:    8月29日,凌晨4点左右,某服务告警,其中一个...
https://support.smartbear.comeadyapi/docs/soapui/steps/g...
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能...
Scala和Java为静态语言,Groovy为动态语言Scala:函数式编程,...
出处:https://www.jianshu.com/p/ce6f8a1f66f4一、一些内部...
在运行groovy的junit方法时,报了这个错误:java.lang.Excep...