Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用ASM或CGLib的Java依赖项注入_Java_Dependency Injection_Java Bytecode Asm_Cglib_Bytecode Manipulation - Fatal编程技术网

使用ASM或CGLib的Java依赖项注入

使用ASM或CGLib的Java依赖项注入,java,dependency-injection,java-bytecode-asm,cglib,bytecode-manipulation,Java,Dependency Injection,Java Bytecode Asm,Cglib,Bytecode Manipulation,我有一个相当大的Java代码库(~15k文件),我没有访问源代码的权限,但是,我想在运行时修改某些类,并将代码注入某些方法中,以便也调用我的代码 由于技术问题,我无法反编译/重新编译并从那里开始。类文件由本机代码加载,并从自定义存档格式提取,然后使用自定义类加载器加载。但是,我可以相当轻松地在JVM实例的上下文中执行Java代码 我的目标是做如下事情: 例如,假设代码中有一个类: class Theirs { public Theirs() { //.... }

我有一个相当大的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

所以现在我想我需要做的是编写我自己的(或修改他们的)类加载器,查找我感兴趣修改的类,注入我的修改,然后使用类似ASM的东西从那里开始。(我使用JVMTI和C++做了类似的事情,但是编译/调试过程非常耗时)


然而,在我这么做之前,我希望有一种类似于CGLib代理的工作方式,即库处理所需的字节码修改,但这并不要求我实际实例化所述增强类的实例。

我不知道
CGLIB
是否是将Java代码注入Java类的理想选择-但有两种类似于f.e.javassist的框架可用,它们提供了一种以Java为中心的方式将代码注入非密封Java类:


例如,我曾经使用javassist为大学课程创建了一个插件机制。希望代码示例有帮助:

看起来很有趣。javassist看起来非常容易注入代码。但是我有一个问题,你如何获得代码的执行?所以你需要访问你正在扩展的应用程序的jar?我的意思是,假设你正在扩展的应用程序名为foo。要运行它,需要执行java-jarfoo.jar。在正常情况下,如何向foo.jar添加插件