2017-04-20 4 views
0

これは私の使用例です。インターセプトしたいクラスが複数ありますが、このクラスのすべてのメソッドをインターセプトしたくありません。私はこれを達成するために同じインターセプタクラスの異なるインスタンスを使いたいと思っています。私がこれをしようとすると、私はByte Buddyから理解できない動作を見ています。私はそれが私が理解していないもの、あるいは私が間違っているものだとはかなり確信していますが、私は困惑しています。私はByte Buddy 1.6.9を使用しています。複数のメソッドのインターセプトとインターセプタの再利用

public class MyClass 
{ 
    private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); 

    public void firstInterceptedMethod() 
    { 
     logger.info("firstInterceptedMethod"); 
    } 

    public void secondInterceptedMethod() 
    { 
     logger.info("secondInterceptedMethod");  
    } 

    public void notInterceptedMethod() 
    { 
     logger.info("notInterceptedMethod");   
    } 
} 

インターセプタクラス:

public class MyInterceptor 
{ 
    private Logger logger = LoggerFactory.getLogger(this.getClass().getName()); 

    private final UUID identifier = UUID.randomUUID(); 

    @RuntimeType 
    public Object methodCalled(@SuperCall Callable<?> superCall, @Origin Method method) throws Exception 
    { 
     logger.info("methodCalled: identifier: " + identifier); 
     logger.info("methodCalled: method name: " + method.getName()); 

     return superCall.call(); 
    } 

} 

バイトバディテスト/計測:

public class MyTest 
{ 
    @Test 
    public void test() throws Exception 
    { 
     MyInterceptor firstMethodInterceptor = new MyInterceptor(); 
     MyInterceptor secondMethodInterceptor = new MyInterceptor(); 

     MyClass myClass = new ByteBuddy().subclass(MyClass.class) 
       .method(ElementMatchers.named("firstInterceptedMethod")) 
         .intercept(MethodDelegation.to(firstMethodInterceptor)) 
       .method(ElementMatchers.named("secondInterceptedMethod")) 
         .intercept(MethodDelegation.to(secondMethodInterceptor)) 
       .make() 
       .load(MyClass.class.getClassLoader()) 
       .getLoaded() 
       .newInstance(); 

     myClass.firstInterceptedMethod(); 
     myClass.secondInterceptedMethod(); 
    } 
} 

出力:

04/20/2017 08:27:26:600 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: identifier: 04124951-f865-4815-8bd4-0b10c0c816a2 
04/20/2017 08:27:26:600 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: identifier: 04124951-f865-4815-8bd4-0b10c0c816a2 
04/20/2017 08:27:26:613 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: method name: firstInterceptedMethod 
04/20/2017 08:27:26:613 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: method name: firstInterceptedMethod 
04/20/2017 08:27:26:614 AM [main] bytebuddy.test.MyClass firstInterceptedMethod : INFO firstInterceptedMethod 
04/20/2017 08:27:26:614 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: identifier: 79590462-b87d-4125-9e87-5481e1062b05 
04/20/2017 08:27:26:614 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: identifier: 79590462-b87d-4125-9e87-5481e1062b05 
04/20/2017 08:27:26:614 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: method name: secondInterceptedMethod 
04/20/2017 08:27:26:614 AM [main] bytebuddy.test.MyInterceptor methodCalled : INFO methodCalled: method name: secondInterceptedMethod 
04/20/2017 08:27:26:614 AM [main] bytebuddy.test.MyClass secondInterceptedMethod : INFO secondInterceptedMethod 
その方法私はインターセプトしたい

クラス

私の質問は、なぜ各インターセプタが2回呼び出されているのですか?最初のメソッドを呼び出すと、最初のインターセプタインスタンスが2回呼び出されたように見えますが、なぜこのことがわかりません。 2番目のメソッドと同様の動作は、2番目のインターセプタインスタンスだけが2回呼び出されるようです。インターセプタは、インターセプトされたメソッドの呼び出しごとに1回しか呼び出されません。

私はのような何かを行う場合は、次の

FirstMethodInterceptor firstMethodInterceptor = new FirstMethodInterceptor(); 
    SecondMethodInterceptor secondMethodInterceptor = new SecondMethodInterceptor(); 

を、私は私が期待する行動を参照してください。すなわち、各インターセプタは、インターセプトされた方法ごとに1回だけ呼び出される。私はこれを避けたいと思っています。私は、この振る舞いを見ることなく '共通の'傍受者を再利用できるようにしたいと考えています。洞察は非常に感謝される、ありがとう。

答えて

0

ええ、いつものように私は間違っています。これは、ロガーのアーティファクトであり、Byte Buddyのアーティファクトではありません。同じロガーインスタンスに対して複数のロギングハンドラーが登録されており、これが原因です。