2017-04-20 124 views
0

这里是我的用例:我有一个类有多个方法,我想拦截,但我不想拦截这个类的所有方法。我想使用同一个拦截器类的不同实例来实现这一点。当我尝试这样做时,我看到了Byte Buddy无法理解的行为。我很确定这是我不明白的事情和/或我做错了什么,但我很难过。我使用的是Byte Buddy 1.6.9。多重方法拦截和拦截器重用

I类要拦截其方法:

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 

我的问题是:为什么我看到每个拦截器被调用两次?当调用第一个方法时,第一个拦截器实例似乎被调用两次,我不明白为什么会这样。与第二种方法类似的行为,只有第二个拦截器实例似乎被调用两次。我希望拦截器只能在拦截方法调用时调用一次。

如果我做这样的事情:

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

然后我看到了我所期望的行为;即每个拦截器仅在每个拦截的方法中被调用一次。我希望避免这种情况,因为我希望能够在不看到这种行为的情况下重用“通用”拦截器。 Insight将非常感谢,谢谢。

回答

0

是的,像往常一样,这是我做错了。这是记录器的人工制品,而不是Byte Buddy。正在为同一个记录器实例注册多个日志记录处理程序,这就是造成这种情况的原因。