This commit is contained in:
@@ -60,6 +60,42 @@ public final class Rest {
|
|||||||
private Rest() {
|
private Rest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class MethodParamClassVisitor extends ClassVisitor {
|
||||||
|
|
||||||
|
private final Map<String, List<String>> fieldmap;
|
||||||
|
|
||||||
|
public MethodParamClassVisitor(int api, final Map<String, List<String>> fieldmap) {
|
||||||
|
super(api);
|
||||||
|
this.fieldmap = fieldmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||||
|
if (java.lang.reflect.Modifier.isStatic(access)) return null;
|
||||||
|
List<String> fieldnames = new ArrayList<>();
|
||||||
|
fieldmap.put(name + ":" + desc, fieldnames);
|
||||||
|
return new MethodVisitor(Opcodes.ASM5) {
|
||||||
|
@Override
|
||||||
|
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
||||||
|
if (index > 0) fieldnames.add(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多
|
||||||
|
public static Map<String, List<String>> getMethodParamNames(Class clazz) {
|
||||||
|
String n = clazz.getName();
|
||||||
|
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
|
||||||
|
Map<String, List<String>> map = new HashMap<>();
|
||||||
|
if (in == null) return map;
|
||||||
|
try {
|
||||||
|
new ClassReader(Utility.readBytesThenClose(in)).accept(new MethodParamClassVisitor(Opcodes.ASM5, map), 0);
|
||||||
|
} catch (Exception e) { //无需理会
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static String getWebModuleName(Class<? extends Service> serviceType) {
|
static String getWebModuleName(Class<? extends Service> serviceType) {
|
||||||
final RestService controller = serviceType.getAnnotation(RestService.class);
|
final RestService controller = serviceType.getAnnotation(RestService.class);
|
||||||
if (controller == null) return serviceType.getSimpleName().replaceAll("Service.*$", "").toLowerCase();
|
if (controller == null) return serviceType.getSimpleName().replaceAll("Service.*$", "").toLowerCase();
|
||||||
@@ -217,6 +253,7 @@ public final class Rest {
|
|||||||
if (entrys.isEmpty()) return null; //没有可WebMapping的方法
|
if (entrys.isEmpty()) return null; //没有可WebMapping的方法
|
||||||
|
|
||||||
//将每个Service可转换的方法生成HttpServlet对应的WebMapping方法
|
//将每个Service可转换的方法生成HttpServlet对应的WebMapping方法
|
||||||
|
final Map<String, List<String>> asmParamMap = MethodParamClassVisitor.getMethodParamNames(serviceType);
|
||||||
for (final MappingEntry entry : entrys) {
|
for (final MappingEntry entry : entrys) {
|
||||||
final Method method = entry.mappingMethod;
|
final Method method = entry.mappingMethod;
|
||||||
final Class returnType = method.getReturnType();
|
final Class returnType = method.getReturnType();
|
||||||
@@ -263,11 +300,12 @@ public final class Rest {
|
|||||||
final int maxStack = 3 + params.length;
|
final int maxStack = 3 + params.length;
|
||||||
List<int[]> varInsns = new ArrayList<>();
|
List<int[]> varInsns = new ArrayList<>();
|
||||||
int maxLocals = 4;
|
int maxLocals = 4;
|
||||||
int argIndex = 0;
|
|
||||||
|
|
||||||
|
List<String> asmParamNames = asmParamMap == null ? null : asmParamMap.get(method.getName() + ":" + Type.getMethodDescriptor(method));
|
||||||
List<Object[]> paramlist = new ArrayList<>();
|
List<Object[]> paramlist = new ArrayList<>();
|
||||||
//解析方法中的每个参数
|
//解析方法中的每个参数
|
||||||
for (final Parameter param : params) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
final Parameter param = params[i];
|
||||||
final Class ptype = param.getType();
|
final Class ptype = param.getType();
|
||||||
String n = null;
|
String n = null;
|
||||||
String comment = "";
|
String comment = "";
|
||||||
@@ -310,13 +348,14 @@ public final class Rest {
|
|||||||
if (annpara != null) required = annpara.required();
|
if (annpara != null) required = annpara.required();
|
||||||
if (n == null) n = (annpara == null || annpara.name().isEmpty()) ? null : annpara.name();
|
if (n == null) n = (annpara == null || annpara.name().isEmpty()) ? null : annpara.name();
|
||||||
if (n == null && ptype == userType) n = "&"; //用户类型特殊处理
|
if (n == null && ptype == userType) n = "&"; //用户类型特殊处理
|
||||||
|
if (n == null && asmParamNames != null && asmParamNames.size() > i) n = asmParamNames.get(i);
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
if (param.isNamePresent()) {
|
if (param.isNamePresent()) {
|
||||||
n = param.getName();
|
n = param.getName();
|
||||||
} else if (ptype == Flipper.class) {
|
} else if (ptype == Flipper.class) {
|
||||||
n = "flipper";
|
n = "flipper";
|
||||||
} else {
|
} else {
|
||||||
n = (++argIndex > 1) ? ("bean" + argIndex) : "bean";
|
n = ("bean" + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (annhead == null && anncookie == null && annaddr == null
|
if (annhead == null && anncookie == null && annaddr == null
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ public interface Creator<T> {
|
|||||||
if (constructorDesc != null && !constructorDesc.equals(desc)) return null;
|
if (constructorDesc != null && !constructorDesc.equals(desc)) return null;
|
||||||
if (this.started) return null;
|
if (this.started) return null;
|
||||||
this.started = true;
|
this.started = true;
|
||||||
|
//返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多
|
||||||
return new MethodVisitor(Opcodes.ASM5) {
|
return new MethodVisitor(Opcodes.ASM5) {
|
||||||
@Override
|
@Override
|
||||||
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
||||||
@@ -113,7 +114,7 @@ public interface Creator<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, String constructorDesc) {
|
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramcount, String constructorDesc) {
|
||||||
String n = clazz.getName();
|
String n = clazz.getName();
|
||||||
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
|
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
|
||||||
if (in == null) return null;
|
if (in == null) return null;
|
||||||
@@ -131,10 +132,18 @@ public interface Creator<T> {
|
|||||||
final List<String> fieldnames = new ArrayList<>();
|
final List<String> fieldnames = new ArrayList<>();
|
||||||
new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM5, fieldnames, constructorDesc), 0);
|
new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM5, fieldnames, constructorDesc), 0);
|
||||||
if (fieldnames.isEmpty()) return null;
|
if (fieldnames.isEmpty()) return null;
|
||||||
return getConstructorField(clazz, fieldnames.toArray(new String[fieldnames.size()]));
|
if (paramcount == fieldnames.size()) {
|
||||||
|
return getConstructorField(clazz, paramcount, fieldnames.toArray(new String[fieldnames.size()]));
|
||||||
|
} else {
|
||||||
|
String[] fs = new String[paramcount];
|
||||||
|
for (int i = 0; i < fs.length; i++) {
|
||||||
|
fs[i] = fieldnames.get(i);
|
||||||
|
}
|
||||||
|
return getConstructorField(clazz, paramcount, fs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, String[] names) {
|
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramcount, String[] names) {
|
||||||
SimpleEntry<String, Class>[] se = new SimpleEntry[names.length];
|
SimpleEntry<String, Class>[] se = new SimpleEntry[names.length];
|
||||||
for (int i = 0; i < names.length; i++) { //查询参数名对应的Field
|
for (int i = 0; i < names.length; i++) { //查询参数名对应的Field
|
||||||
try {
|
try {
|
||||||
@@ -147,7 +156,7 @@ public interface Creator<T> {
|
|||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, Parameter[] params) {
|
public static SimpleEntry<String, Class>[] getConstructorField(Class clazz, int paramcount, Parameter[] params) {
|
||||||
SimpleEntry<String, Class>[] se = new SimpleEntry[params.length];
|
SimpleEntry<String, Class>[] se = new SimpleEntry[params.length];
|
||||||
for (int i = 0; i < params.length; i++) { //查询参数名对应的Field
|
for (int i = 0; i < params.length; i++) { //查询参数名对应的Field
|
||||||
try {
|
try {
|
||||||
@@ -232,7 +241,7 @@ public interface Creator<T> {
|
|||||||
for (Constructor c : clazz.getConstructors()) {
|
for (Constructor c : clazz.getConstructors()) {
|
||||||
ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class);
|
ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class);
|
||||||
if (cp == null) continue;
|
if (cp == null) continue;
|
||||||
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, cp.value());
|
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value());
|
||||||
if (fields != null) {
|
if (fields != null) {
|
||||||
constructor0 = c;
|
constructor0 = c;
|
||||||
constructorParameters0 = fields;
|
constructorParameters0 = fields;
|
||||||
@@ -250,7 +259,7 @@ public interface Creator<T> {
|
|||||||
//优先参数最多的构造函数
|
//优先参数最多的构造函数
|
||||||
cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount());
|
cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount());
|
||||||
for (Constructor c : cs) {
|
for (Constructor c : cs) {
|
||||||
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, Type.getConstructorDescriptor(c));
|
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c));
|
||||||
if (fields != null) {
|
if (fields != null) {
|
||||||
constructor0 = c;
|
constructor0 = c;
|
||||||
constructorParameters0 = fields;
|
constructorParameters0 = fields;
|
||||||
@@ -263,7 +272,7 @@ public interface Creator<T> {
|
|||||||
if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue;
|
if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue;
|
||||||
ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class);
|
ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class);
|
||||||
if (cp == null) continue;
|
if (cp == null) continue;
|
||||||
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, cp.value());
|
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value());
|
||||||
if (fields != null) {
|
if (fields != null) {
|
||||||
constructor0 = c;
|
constructor0 = c;
|
||||||
constructorParameters0 = fields;
|
constructorParameters0 = fields;
|
||||||
@@ -282,7 +291,7 @@ public interface Creator<T> {
|
|||||||
//优先参数最多的构造函数
|
//优先参数最多的构造函数
|
||||||
cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount());
|
cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount());
|
||||||
for (Constructor c : cs) {
|
for (Constructor c : cs) {
|
||||||
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, Type.getConstructorDescriptor(c));
|
SimpleEntry<String, Class>[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c));
|
||||||
if (fields != null) {
|
if (fields != null) {
|
||||||
constructor0 = c;
|
constructor0 = c;
|
||||||
constructorParameters0 = fields;
|
constructorParameters0 = fields;
|
||||||
|
|||||||
Reference in New Issue
Block a user