Here's my use case: I have a class that has multiple methods that I want to intercept, but I don't want to intercept all methods of this class. I want to use different instances of the same interceptor class to accomplish this. When I try to do this, I'm seeing behavior that I don't understand from Byte Buddy. I'm pretty sure it's something I don't understand and/or something I'm doing wrong, but I'm stumped. I'm using Byte Buddy 1.6.9.
Class whose methods I want to intercept:
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");
}
}
Interceptor class:
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();
}
}
Byte Buddy test/instrumentation:
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();
}
}
Output:
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
My question is: Why am I seeing each interceptor getting called twice? When calling the first method, the first interceptor instance appears to get called twice, and I don't understand why this is. Similar behavior with the second method, only the second interceptor instance appears to get called twice. I would expect the interceptor to only get called once per intercepted method invocation.
If I do something like:
FirstMethodInterceptor firstMethodInterceptor = new FirstMethodInterceptor();
SecondMethodInterceptor secondMethodInterceptor = new SecondMethodInterceptor();
then I see behavior that I would expect; i.e., each interceptor is only called once per intercepted method. I'm hoping to avoid this as I would like to be able to reuse a 'common' interceptor without seeing this behavior. Insight would be much appreciated, thanks.