簡體   English   中英

使用ASM或CGLib的Java依賴項注入

[英]Java dependency injection using ASM or CGLib

我有一個相當大的Java代碼庫(〜15k文件),但我無法訪問源代碼,但是,我想在運行時修改某些類並將代碼注入某些方法中以也調用我的代碼。

由於技術問題,我無法反編譯/重新編譯然后再去那里。 類文件由本機代碼加載,並從自定義存檔格式中提取並使用自定義類加載器加載。 但是,我可以很容易地在其JVM實例的上下文中執行Java代碼。

我的目標是執行以下操作:

例如,說在代碼中有一個類:

class Theirs {

    public Theirs() {
        //....
    }

    public String getName() {
        return "Theirs";
    }
}

在我的代碼中,我有:

class Mine 
{
    public static Theirs theirs_ = null;
    public static void myMethod(Theirs theirs) { 
        theirs_ = theirs;
    }
}

我想修改他們的每個實例,使其表現如下:

class Theirs { 
    public Theirs() {
        Mine.myMethod(this);
    }
}

這樣我就可以執行以下操作:

System.out.println(Mine.theirs_.getName());

我以為CGLib代理可以實現這一點,但是使用代理,開銷比較高,這是因為字符串比較方法可能每秒被調用數十萬次,無論如何,我發現為了擁有增強對象的實例,您需要自己實例化它們。IE:並非您增強的類的所有實例實際上都得到了增強,例如:

public static void main( String[] args )
{
    Object proxy = Enhancer.create(Object.class, new HashCodeAlwaysZeroMethodInterceptor());
    System.out.println(new Object().hashCode());
    System.out.println(proxy.hashCode());

}

第一個println打印實際對象哈希,而不是預期的0。

所以現在我在想,我需要做的是編寫自己的(或修改他們的)ClassLoader,以查找我想要修改的類,注入修改並使用諸如ASM之類的方法從那里進行修改。 (我使用JVMTI和C ++做過類似的事情,但是編譯/調試過程非常耗時)

但是,在執行此操作之前,我希望有某種類似於CGLib代理的工作方式,因為該庫負責所需的字節碼修改,但這並不需要我實際實例化所述增強類的實例。 。

我不知道CGLIB是否適合將Java代碼注入Java類中-但是有一些像fe javassist這樣的框架可用,它們提供了以Java為中心的方式將代碼注入未密封的Java類中: http:// www。 csg.ci.iu-tokyo.ac.jp/~chiba/javassist/

例如,一旦使用javassist,就必須為大學課程創建一個插件機制。 希望代碼示例對您有所幫助: https : //github.com/RovoMe/PluginApplication/blob/master/PluginFramework/PluginCore/src/main/java/at/rovo/core/classloader/InjectionLoaderStrategyDecorator.java

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM