私は、サービスにミックスインするカテゴリに公開閉鎖として入れた同様のものを書きました:
// 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: Doing a lot of work takes nn ms」のログ出力が得られ、メソッドの戻り値として内部クロージャーの値が返されますdoSomeWork
。
taglib インスタンスの場合out << ...
は、
timer "Writing an emoticon", {
// your code
}
コード。
内部の戻り値を渡すことを気にしない場合は、代わりにクロージャ呼び出しの結果として期間を返すことができます。
更新:
私は読み間違えたかもしれません.taglibコードをまったく変更せずにtaglib実行をラップする方法を尋ねていますか? body を受け取り、実行のために他の taglibs に渡すカスタム 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:
わかりましたので、試してみました。正常に動作します。最終的なコード (期間を返す 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
また、ログにも書き込みました。