Methods Javassist-为什么我可以';在执行过程中被拦截后,是否替换方法体?
我试图用Methods Javassist-为什么我可以';在执行过程中被拦截后,是否替换方法体?,methods,call,instrumentation,javassist,bytecode-manipulation,Methods,Call,Instrumentation,Javassist,Bytecode Manipulation,我试图用instrument替换主类中声明的方法。这段代码将在执行过程中拦截所有方法调用,但它不会替换某个方法的方法体(change) BeanMain.java package application; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.NotFoundException; import javassis
instrument
替换主类中声明的方法。这段代码将在执行过程中拦截所有方法调用,但它不会替换某个方法的方法体(change
)
BeanMain.java
package application;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
public class BeanMain {
private Bean bean;
public BeanMain(){
bean = new Bean("old_a", "old_b");
}
public void print(){
System.out.format("\n%-25s %5s %5s\n", "[BeanMain]", bean.getA(), bean.getB());
}
public void change(String pre){
bean.setParam(pre+"A", pre+"B");
}
public static void main(String[] args) throws NotFoundException, CannotCompileException {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.get("application.BeanMain");
ctClass.instrument(new ExprEditor(){
@Override
public void edit(MethodCall m) throws CannotCompileException {
System.out.println(m.getMethodName());
if(m.getMethodName().equals("change"))
m.replace("{System.out.println(\"$1\"); $_ = $proceed($$);}");
}
});
BeanMain inst = new BeanMain();
inst.print();
inst.change("new_");
inst.print();
}
}
java
package application;
public class Bean {
private String a;
private String b;
public Bean(){}
public Bean(String a, String b) {
this.a = a;
this.b = b;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public void setParam(String a, String b){
this.a = a;
this.b = b;
}
public void doSomething(){
System.out.println("Doing something.");
}
}
我的问题类加载相关吗?你必须下定决心。是否要替换方法调用或方法声明的主体?假设我要替换方法调用,在这种情况下
replace()
method是否受到限制?如果要替换方法调用,“它不会替换方法主体”不是错误。很难说更换电话是否有效。名为change
的方法的唯一方法调用发生在已运行的main
方法中。插装不会取代方法的执行,只会取代后续的执行。因此,根据您最后一句话,我能插装BeanMain类加载的类所调用的方法吗?我从未为此使用过Javassist,所以我不能说任何关于CtClass.instrument
,但原则上,HotSpot JVM的检测工具能够替换后续调用的所有方法。因此,假设Javassist在其上运行,这应该是可能的。如果在插入指令后再次调用main
方法,它甚至应该可以工作。