2015-01-11 51 views
6

假設我有一個方法m可以Byte Buddy訪問方法的本地變量名稱嗎?

public void m() { 
    String foo = "foo"; 
    int bar = 0; 
    doSomething(foo, bar); 
} 

我想用ByteBuddy儀器代碼,以便調用mdoSomething時,它會自動把的foobar值成HashMap,相當多的東西看起來像:

public void m() { 
    String foo = "foo"; 
    int bar = 0; 
    context.put("foo", foo); // new code injected 
    context.put("bar", bar); // new code injected 
    doSomething(foo, bar); 
} 

有無論如何通過ByteBuddy做這個儀器?

+0

好,使用ASM,這當然是可能的,但這不是你想要聽到的...... – fge

+0

你能否爲這種情況提供ASM解決方案? thx ...綠色 –

回答

1

Byte Buddy有內置的方式,以這種方式重新定義方法m。不過,Byte Buddy主動公開了實施Byte Buddy的ASM API。 ASM提供了相當豐富的文檔,可以告訴你如何做到這一點。然而,我可以告訴你,這將是相當多的代碼。請注意,您需要編譯任何啓用了調試符號的方法,否則這些內部變量在運行時不可用。

你是否確定要這樣做?不知道你的確切用例,感覺這是一個壞主意。通過實現此解決方案,您可以將局部變量的名稱作爲應用程序的一部分,而不是讓它們成爲實現細節。

因此,我會建議你採用doSomething方法。請問這就夠了yourn什麼很容易在字節好友使用類似的攔截做了以下內容:

class Interceptor { 
    void intercept(@Origin Method method, @AllArguments Object[] args) { 
    int index = 0; 
    for(Parameter p : method.getParameters()) { 
     context.add(p.getName(), args[index++]); 
    } 
    } 
} 

那麼這個攔截器可以使用如下:

MethodDelegation.to(new Interceptor()).andThen(SuperMethodCall.INSTANCE); 
+0

'doSomething'將採用任意的參數:'void doSomething(Object ... args)'所以我不能用這種方法。這個場景是實現一個Controller方法處理器,所以當用戶調用'render(foo,bar)'時,它會自動將'foo'和'bar'放入渲染的參數圖中,該參數圖在下劃線模板視圖代碼 –

+0

中引用。在這種情況下,你將不得不使用ASM並確保你添加了調試符號。攔截Byte Buddy最小的實體知道是一種方法,我懷疑這將在未來發生變化。您仍然可以使用Byte Buddy提供基礎設施,但除此之外您需要使用ASM。 –

相關問題