1

Java では、ロギングを Java クラスに透過的に追加するために使用できますAspectJ(または、おそらく他のバイト コード計測ツールを使用します)。今、Scala関数に透過的にロギングを追加する方法を考えています。

関数を変換するツールが欲しいfoo

def foo(x:Int) = x + 1

そのようなものに:

def foo(x:Int) = {
   log.trace("Enter foo with x = " + x) // 自動的に追加
   値 r = x + 1
   log.trace("Exit foo with r = " + r) // 自動的に追加  
   r
}

Scala 関数にログを透過的に追加するにはどうすればよいでしょうか?

4

1 に答える 1

2

AspectJ は Scala コードで問題なく動作します。def >Scala の名前マングリング ルール (つまり、 become ) に従う必要があるだけですdef $gt

あなたが持っていると仮定します

class Foo {
  def foo(x: Int) {
  }
  def bar() { }
}

ログを追加するには、Java AspectJ 構文を使用して、

"org.aspectj" % "aspectjweaver" % "1.7.2",
"org.aspectj" % "aspectjrt" % "1.7.2"

あなたにbuild.sbt。次に進むと、次の側面を持つことができます。

@Aspect
public class MonitorAspect {

    @Pointcut(value = "execution (* your.package.Foo.*(..))")
    public void methodsInFoo() {}

    @Before("methodsInFoo()")
    public void enter(JoinPoint jp) {
        // log
    }

    @After("methodsInFoo()")
    public void exit(JoinPoint jp) {
    }
}

最後の部分はMETA-INF/aop.xml、ロード時のウィーバーの作業を定義する です。

<aspectj>

    <aspects>
        <aspect name="your.package.MonitorAspect"/>
    </aspects>

    <weaver options="-XnoInline">
        <include within="your.package.*"/>
    </weaver>

</aspectj>

最後に、JVM を起動して-javaagent:$PATH_TO_ASPECTJWEAVER.JAR準備完了です。


あなたの場合、高階関数の使用を検討する価値があるかもしれません。単なる例としてロギングを使用していて、内部関数の前後で実際何かを行っている場合は、HOF の使用を検討する必要があります。

def logged[U](f: => U): U = {
    log.info("Before")
    val ret = f
    log.info("After")
    ret
}

ここには、logged別の関数を受け取りf、ログを処理し、何でも行う関数fがあります。

于 2013-06-02T09:22:40.953 に答える