项目需要,想根据SpringMvc的传入地址做二次反射跳转,用java.lang.reflect包的反射机制找不到参数的具体名称,找到了@MikanMu大神的代码,稍微改造了一下,记起来以作备忘。
通过ASM来读取:
需要引入相应的jar包.
pom.xml引入:
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>5.1</version>
</dependency>
类中import:
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.Label;
以下是实现代码:代码是抄来的:原文:http://blog.csdn.net/mhmyqn/article/details/47294485
感谢原文作者,写的很多原理性的东西很棒,不过我本地的项目引用了Spring会造成包import *不能正确识别,所以加了import,而asm也发展到6.0了,我引入的是5.1版本。
private static String[] getMethodParameterNamesByAsm4(Class<?> clazz,
final Method method) {
final Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes == null || parameterTypes.length == 0) {
return null;
}
final Type[] types = new Type[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
types[i] = Type.getType(parameterTypes[i]);
}
final String[] parameterNames = new String[parameterTypes.length];
String className = clazz.getName();
int lastDotIndex = className.lastIndexOf(".");
className = className.substring(lastDotIndex + 1) + ".class";
InputStream is = clazz.getResourceAsStream(className);
try {
ClassReader classReader = new ClassReader(is);
classReader.accept(new ClassVisitor(Opcodes.ASM4) {
@Override
public MethodVisitor visitMethod(int access, String name,
String desc, String signature, String[] exceptions) {
// 只处理指定的方法
Type[] argumentTypes = Type.getArgumentTypes(desc);
if (!method.getName().equals(name)
|| !Arrays.equals(argumentTypes, types)) {
return null;
}
return new MethodVisitor(Opcodes.ASM4) {
@Override
public void visitLocalVariable(String name,
String desc, String signature, Label start,
Label end, int index) {
// 静态方法第一个参数就是方法的参数,如果是实例方法,第一个参数是this
if (Modifier.isStatic(method.getModifiers())) {
parameterNames[index] = name;
} else if (index > 0) {
parameterNames[index - 1] = name;
}
}
};
}
}, 0);
} catch (IOException e) {
e.printStackTrace();
}
// 把参数类型和参数名组合一下,用:分割
for (int i = 0; i < parameterNames.length; i++) {
parameterNames[i] = parameterTypes[i].getName() + ":"
+ parameterNames[i];
}
return parameterNames;
}