设计模式,覆盖方法而无需重新编译/重新链接

Sid*_*rth 1 java design-patterns

我们正在构建一个需要在生产环境中运行的产品.我们需要修改现有库的一些功能.现有的库有类和方法,我们需要覆盖一个或多个方法,以便调用者使用我们的重写方法而不是原始库.

OriginalLibrary

package com.original.library ;
public class OriginalLibrary {
    public int getValue() {
        return 1 ;
    }
    public int getAnotherValue() {
        return 1 ;
    }
}
Run Code Online (Sandbox Code Playgroud)

原始客户

public class MyClient {
    private OriginalLibraryClass originalLibraryObject ;
    public MyClient () {
        originalLibraryObject = new OriginalLibraryClass() ;
        System.out.println(originalLibraryObject.getValue()) ;
        System.out.println(originalLibraryObject.getAnotherValue()) ;
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

1

2

现在,我需要getValue()改为返回3,而不是1

需要的输出

3

2

package com.original.library.improved ;
    public class OriginalLibrary extends com.original.library.OriginalLibrary {
        public int getValue() {
            return 3 ;
        }
        public int getAnotherValue() {
            return super.getAnotherValue() ;
        }
}
Run Code Online (Sandbox Code Playgroud)

如果我这样做,我需要告诉我Original Client重新排序并使用我之前的com.original.library.improvedjar文件. com.original.library

我几乎确信这是non intrusive way推出我的改进服务的最重要的OriginalLibrary.我更喜欢一个解决方案,我需要告诉客户只需添加我的jar文件,无需重新编译,重新链接客户端代码.

类似的(不一样)在谷歌搜索的问题, 在这里 在这里

Nav*_*wat 5

java assist是用于字节码操作的优秀库.我根据您给出的示例代码修改了下面的代码,您必须更多地探索javaassist以满足您的实际需求

CtClass etype = ClassPool.getDefault().get("com.original.library.OriginalLibrary");
// get method from class
CtMethod cm = etype.getDeclaredMethod("getValue");
// change the method bosy
cm.setBody("return 3;");
etype.rebuildClassFile();
// give the path where classes is placed, In my eclipse it is bin
etype.writeFile("bin");


OriginalLibrary originalLibraryObject;
originalLibraryObject = new OriginalLibrary();
System.out.println(originalLibraryObject.getValue());
System.out.println(originalLibraryObject.getAnotherValue());
Run Code Online (Sandbox Code Playgroud)

现在getValue的输出是3,因为我改变了该方法的主体.