2017-03-02 100 views
2

我有一個premain(),其中所有使用某個註釋標註的方法都應該委託給某個類。在一般情況下,我是這樣的:ByteBuddy MethodDelegation在Java代理中不起作用

public static void premain(final String agentArguments, final Instrumentation instrumentation) { 

    CountingInterception ci = new CountingInterception(); 

    new AgentBuilder.Default() 
    .type(ElementMatchers.isAnnotatedWith(com.codahale.metrics.annotation.Counted.class)) 
     .transform((builder, type, classLoader, module) -> 
     builder.method(ElementMatchers.any()) 
       .intercept(MethodDelegation.to(ci)) 
    ).installOn(instrumentation); 
} 

使用調試器顯示,這部分被處理,但如果註解的方法被調用時,沒有任何反應。

的CountingInterception看起來像這樣

public class CountingInterception { 

    @RuntimeType 
    public Object intercept(@DefaultCall final Callable<?> zuper, @Origin final Method method, @AllArguments final Object... args) throws Exception { 

    String name = method.getAnnotation(Counted.class).name(); 
    if (name != null) { 
     // do something 
    } 

    return zuper.call(); 
    } 
} 

感謝任何提示!

使用ByteBuddy 1.6.9

回答

1

我假設你正在嘗試做的東西比一個Java 8默認的方法調用不同。你的意思是使用調用超級方法的@SuperCall

我建議你: 1.減少你的攔截器什麼也不做。創建一個攔截器,將MethodDelegation鏈接到SuperMethodCall。 2.註冊AgentBuilder.Listener將錯誤寫入控制檯。

我相信Byte Buddy無法綁定您的方法,因爲您的攔截器只能應用於提供默認方法實現的類。

+0

謝謝你的提示。 – micfra

1

爲了實現我想做的事,以下更改:

在倍美力:

CountingInterception ci = new CountingInterception(); 

new AgentBuilder.Default() 
    .type(declaresMethod(isAnnotatedWith(Counted.class))) 
     .transform((builder, type, classLoader, module) -> builder 
     .method(isAnnotatedWith(Counted.class)) 
       .intercept(MethodDelegation.to(ci).andThen(SuperMethodCall.INSTANCE)) 
    ).installOn(instrumentation); 

和CountingInterception:

public void interceptor(@Origin final Method method) throws Exception { 

    String name = method.getAnnotation(Counted.class).name(); 
    if (name != null) { 
     // do something 
    } 

}