com.jquicker.args.LocalVariableTableArgsNameDiscoverer Maven / Gradle / Ivy
package com.jquicker.args;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.bytecode.ByteArray;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import javassist.bytecode.MethodParametersAttribute;
import com.jquicker.commons.log.JLogger;
import com.jquicker.exception.LocalVariableTableArgsNameDiscovererException;
/**
* 编译时加上-parameters参数
*
* @author OL
*/
public class LocalVariableTableArgsNameDiscoverer implements ArgsNameDiscoverer {
@Override
public String[] getArgsNames(Method method) {
int count = method.getParameterCount();
String[] argsNames = new String[count];
Class> clazz = method.getDeclaringClass();
if(clazz.isInterface()) {
return this.getInterfaceArgNames(method);
}
ClassPool pool = ClassPool.getDefault();
pool.appendSystemPath();
pool.appendClassPath(new ClassClassPath(clazz));
CtClass cc = null;
try {
cc = pool.get(clazz.getName());
CtMethod ctMethod = cc.getDeclaredMethod(method.getName()); // 这里给出需要分析的方法名
MethodInfo methodInfo = ctMethod.getMethodInfo();
// 如果没有编译任何debug信息,这里getCodeAttribute获取的值为null
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
if (codeAttribute != null) {
// 如果没有编译本地变量信息,这里getAttribute获取的值为null
// 注:本地变量表的顺序不一定是按照代码中变量定义的顺序排列的
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute
.getAttribute(LocalVariableAttribute.tag);
if (attr != null) {
Tmp[] tmps = new Tmp[attr.tableLength()];
for (int i = 0; i < tmps.length; i++) {
// System.out.print(attr.index(i) + ": " + attr.variableName(i) + " ");
tmps[i] = new Tmp(attr.index(i), attr.variableName(i));
}
Arrays.sort(tmps, new Comparator() {
@Override
public int compare(Tmp o1, Tmp o2) {
return o1.compareTo(o2);
}
});
// System.out.println(ArrayUtils.join(tmps, ","));
boolean isStatic = Modifier.isStatic(method.getModifiers());
int pos = isStatic ? 0 : 1;
for (int i = 0; i < argsNames.length; i++) {
// 非静态方法 第0个参数默认是this
// argsNames[i] = attr.variableName(i + pos);
argsNames[i] = tmps[i + pos].name;
}
}
}
} catch (NotFoundException e) {
JLogger.error(e.getMessage(), e);
} finally {
if (cc != null) {
cc.detach();
}
}
return argsNames;
}
@Override
public String[] getArgsNames(Constructor> ctor) {
int count = ctor.getParameterCount();
String[] argsNames = new String[count];
Class> clazz = ctor.getDeclaringClass();
ClassPool pool = ClassPool.getDefault();
pool.appendSystemPath();
pool.appendClassPath(new ClassClassPath(clazz));
CtClass cc = null;
try {
cc = pool.get(clazz.getName());
CtMethod ctMethod = cc.getDeclaredMethod(ctor.getName());
MethodInfo methodInfo = ctMethod.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
if (codeAttribute != null) {
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute
.getAttribute(LocalVariableAttribute.tag);
if (attr != null) {
Tmp[] tmps = new Tmp[attr.tableLength()];
for (int i = 0; i < tmps.length; i++) {
tmps[i] = new Tmp(attr.index(i), attr.variableName(i));
}
Arrays.sort(tmps, new Comparator() {
@Override
public int compare(Tmp o1, Tmp o2) {
return o1.compareTo(o2);
}
});
for (int i = 0; i < argsNames.length; i++) {
argsNames[i] = tmps[i + 1].name;
}
}
}
} catch (NotFoundException e) {
JLogger.error(e.getMessage(), e);
} finally {
if (cc != null) {
cc.detach();
}
}
return argsNames;
}
/**
* 获取接口方法形参名称
* @param method
* @return
* @author OL
*/
private String[] getInterfaceArgNames(Method method) {
int count = method.getParameterCount();
String[] argsNames = new String[count];
ClassPool pool = ClassPool.getDefault();
CtClass cc = null;
try {
cc = pool.get(method.getDeclaringClass().getName());
CtMethod ctMethod = cc.getDeclaredMethod(method.getName());
MethodInfo methodInfo = ctMethod.getMethodInfo();
MethodParametersAttribute methodParameters = (MethodParametersAttribute) methodInfo.getAttribute("MethodParameters");
if(methodParameters == null){
throw new LocalVariableTableArgsNameDiscovererException("若由框架自动实现dao接口,请开启-parameters编译");
}
for (int i = 0; i < count; i++) {
argsNames[i] = methodParameters.getConstPool().getUtf8Info(ByteArray.readU16bit(methodParameters.get(), i * 4 + 1));
}
} catch (NotFoundException e) {
JLogger.error(e.getMessage(), e);
} finally {
if (cc != null) {
cc.detach();
}
}
return argsNames;
}
}
class Tmp {
public int index;
public String name;
public Tmp(int index, String name) {
this.index = index;
this.name = name;
}
public int compareTo(Tmp tmp) {
int i = this.index - tmp.index;
if (i > 0) {
return 1;
} else if (i == 0) {
return 0;
} else {
return -1;
}
}
@Override
public String toString() {
return "Tmp [index=" + index + ", name=" + name + "]";
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy