以前看这块的源码。好像没用asm,直接method.invoke(module, args)的,
然后今天再看下,用了FastMethod.invoke(module, args) 来执行 瞬间糟逼了,,,
请问下大大 下面那块代码 GeneratorAdapter 生成invoke方法后如何添加的方法内容。。还用这里用asm给每个方法都生成一个新的类有啥好处吗。。。
public void process(ActionContext ac) throws Throwable {
Object module = ac.getModule();
Method method = ac.getMethod();
Object[] args = ac.getMethodArgs();
try {
if (Mvcs.disableFastClassInvoker)
ac.setMethodReturn(method.invoke(module, args));
else {
_check(method);
ac.setMethodReturn(fm.invoke(module, args));
}
doNext(ac);
}
}
public static byte[] _make(Class<?> klass,
int mod,
Class<?>[] params,
org.nutz.repo.org.objectweb.asm.commons.Method method,
Class<?> returnType,
String className,
String descriptor) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_5,
ACC_PUBLIC,
className.replace('.', '/'),
null,
"java/lang/Object",
new String[]{FastMethod.class.getName().replace('.', '/')});
Type klassType = Type.getType(klass);
// 首先, 定义默认构造方法
addConstructor(cw, Type.getType(Object.class), org.nutz.repo.org.objectweb.asm.commons.Method.getMethod("void <init> ()"));
// 然后定义执行方法
GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, _M, null, new Type[]{Exception_TYPE}, cw);
if (returnType == null) {
mg.newInstance(klassType);
mg.dup();
}
else if (!Modifier.isStatic(mod)) {
mg.loadThis();
mg.loadArg(0);
mg.checkCast(klassType);
}
if (params.length > 0) {
for (int i = 0; i < params.length; i++) {
mg.loadArg(1);
mg.push(i);
mg.arrayLoad(Type.getType(Object.class));
Type paramType = Type.getType(params[i]);
if (params[i].isPrimitive()) {
mg.unbox(paramType);
} else {
mg.checkCast(paramType);
}
}
}
if (returnType == null) {
mg.invokeConstructor(klassType, method);
} else {
if (Modifier.isStatic(mod)) {
mg.invokeStatic(klassType, method);
} else if (Modifier.isInterface(klass.getModifiers())) {
mg.invokeInterface(klassType, method);
} else {
mg.invokeVirtual(klassType, method);
}
if (Void.class.equals(returnType)) {
mg.visitInsn(ACONST_NULL);
} else if (returnType.isPrimitive()) {
mg.box(Type.getType(returnType));
}
}
Label tmp = new Label();
mg.visitLabel(tmp);
mg.visitLineNumber(1, tmp);
mg.returnValue();
mg.endMethod();
cw.visitSource(klass.getSimpleName() + ".java", null);
cw.visitEnd();
return cw.toByteArray();
}