From b7d7e6567b551b9530470592a6624e8d0522e761 Mon Sep 17 00:00:00 2001 From: Redkale <22250530@qq.com> Date: Thu, 9 Mar 2017 11:19:13 +0800 Subject: [PATCH] --- src/org/redkale/boot/GroupInfo.java | 5 + src/org/redkale/util/Creator.java | 225 ++++++++++++++++++++-------- 2 files changed, 165 insertions(+), 65 deletions(-) diff --git a/src/org/redkale/boot/GroupInfo.java b/src/org/redkale/boot/GroupInfo.java index 1e198d27d..af19499c4 100644 --- a/src/org/redkale/boot/GroupInfo.java +++ b/src/org/redkale/boot/GroupInfo.java @@ -7,6 +7,7 @@ package org.redkale.boot; import java.net.InetSocketAddress; import java.util.*; +import org.redkale.convert.json.JsonConvert; /** * 协议地址组合对象, 对应application.xml 中 resources->group 节点信息 @@ -72,4 +73,8 @@ public class GroupInfo { this.addrs = addrs; } + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } } diff --git a/src/org/redkale/util/Creator.java b/src/org/redkale/util/Creator.java index ef0ce0f12..1247fe139 100644 --- a/src/org/redkale/util/Creator.java +++ b/src/org/redkale/util/Creator.java @@ -12,6 +12,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.reflect.*; import java.net.*; import java.util.*; +import java.util.AbstractMap.SimpleEntry; import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.Type; import static jdk.internal.org.objectweb.asm.Opcodes.*; @@ -80,6 +81,84 @@ public interface Creator { public static @interface ConstructorParameters { String[] value(); + + static class CreatorInner { + + static class SimpleClassVisitor extends ClassVisitor { + + private final String constructorDesc; + + private final List fieldnames; + + private boolean started; + + public SimpleClassVisitor(int api, List fieldnames, String constructorDesc) { + super(api); + this.fieldnames = fieldnames; + this.constructorDesc = constructorDesc; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (java.lang.reflect.Modifier.isStatic(access) || !"".equals(name)) return null; + if (constructorDesc != null && !constructorDesc.equals(desc)) return null; + if (this.started) return null; + this.started = true; + 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); + } + }; + } + } + + public static SimpleEntry[] getConstructorField(Class clazz, String constructorDesc) { + String n = clazz.getName(); + InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class"); + ByteArrayOutputStream out = new ByteArrayOutputStream(1024); + byte[] bytes = new byte[1024]; + int pos; + try { + while ((pos = in.read(bytes)) != -1) { + out.write(bytes, 0, pos); + } + in.close(); + } catch (IOException io) { + return null; + } + final List fieldnames = new ArrayList<>(); + new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM5, fieldnames, constructorDesc), 0); + if (fieldnames.isEmpty()) return null; + return getConstructorField(clazz, fieldnames.toArray(new String[fieldnames.size()])); + } + + public static SimpleEntry[] getConstructorField(Class clazz, String[] names) { + SimpleEntry[] se = new SimpleEntry[names.length]; + for (int i = 0; i < names.length; i++) { //查询参数名对应的Field + try { + Field field = clazz.getDeclaredField(names[i]); + se[i] = new SimpleEntry<>(field.getName(), field.getType()); + } catch (Exception e) { + return null; + } + } + return se; + } + + public static SimpleEntry[] getConstructorField(Class clazz, Parameter[] params) { + SimpleEntry[] se = new SimpleEntry[params.length]; + for (int i = 0; i < params.length; i++) { //查询参数名对应的Field + try { + Field field = clazz.getDeclaredField(params[i].getName()); + se[i] = new SimpleEntry<>(field.getName(), field.getType()); + } catch (Exception e) { + return null; + } + } + return se; + } + } } /** @@ -135,53 +214,86 @@ public interface Creator { return (Creator) Class.forName(newDynName.replace('/', '.')).newInstance(); } catch (Exception ex) { } + Constructor constructor0 = null; - for (Constructor c : clazz.getConstructors()) { //优先找public 的构造函数 - if (c.getParameterCount() == 0) { - constructor0 = c; - break; - } - } - if (constructor0 == null) {//其次找非private带ConstructorProperties的构造函数 - for (Constructor c : clazz.getDeclaredConstructors()) { - if (Modifier.isPrivate(c.getModifiers())) continue; - if (c.getAnnotation(ConstructorProperties.class) != null) { - constructor0 = c; - break; - } - } - } - if (constructor0 == null) {//再次找非private且带-parameters编译项的构造函数 java 8以上才支持 - for (Constructor c : clazz.getDeclaredConstructors()) { - if (Modifier.isPrivate(c.getModifiers())) continue; - Parameter[] params = c.getParameters(); - if (params.length == 0) continue; - boolean flag = true; - for (Parameter param : params) { - try { - clazz.getDeclaredField(param.getName()); - } catch (Exception e) { - flag = false; - break; - } - } - if (flag) { - constructor0 = c; - break; - } - } - } - if (constructor0 == null) {//最后找非private的空构造函数 - for (Constructor c : clazz.getDeclaredConstructors()) { - if (Modifier.isPrivate(c.getModifiers())) continue; + SimpleEntry[] constructorParameters0 = null; //构造函数的参数 + + if (constructor0 == null) { // 1、查找public的空参数构造函数 + for (Constructor c : clazz.getConstructors()) { if (c.getParameterCount() == 0) { constructor0 = c; + constructorParameters0 = new SimpleEntry[0]; + break; + } + } + } + if (constructor0 == null) { // 2、查找public带ConstructorProperties注解的构造函数 + for (Constructor c : clazz.getConstructors()) { + ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class); + if (cp == null) continue; + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, cp.value()); + if (fields != null) { + constructor0 = c; + constructorParameters0 = fields; + break; + } + } + } + if (constructor0 == null) { // 3、查找public且不带ConstructorProperties注解的构造函数 + List cs = new ArrayList<>(); + for (Constructor c : clazz.getConstructors()) { + if (c.getAnnotation(ConstructorProperties.class) != null) continue; + if (c.getParameterCount() < 1) continue; + cs.add(c); + } + //优先参数最多的构造函数 + cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); + for (Constructor c : cs) { + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, Type.getConstructorDescriptor(c)); + if (fields != null) { + constructor0 = c; + constructorParameters0 = fields; + break; + } + } + } + if (constructor0 == null) { // 4、查找非private带ConstructorProperties的构造函数 + for (Constructor c : clazz.getDeclaredConstructors()) { + if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue; + ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class); + if (cp == null) continue; + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, cp.value()); + if (fields != null) { + constructor0 = c; + constructorParameters0 = fields; + break; + } + } + } + if (constructor0 == null) { // 5、查找非private且不带ConstructorProperties的构造函数 + List cs = new ArrayList<>(); + for (Constructor c : clazz.getDeclaredConstructors()) { + if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue; + if (c.getAnnotation(ConstructorProperties.class) != null) continue; + if (c.getParameterCount() < 1) continue; + cs.add(c); + } + //优先参数最多的构造函数 + cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); + for (Constructor c : cs) { + SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, Type.getConstructorDescriptor(c)); + if (fields != null) { + constructor0 = c; + constructorParameters0 = fields; break; } } } final Constructor constructor = constructor0; - if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); + final SimpleEntry[] constructorParameters = constructorParameters0; + if (constructor == null || constructorParameters == null) { + throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); + } //------------------------------------------------------------- ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); FieldVisitor fv; @@ -189,7 +301,7 @@ public interface Creator { AnnotationVisitor av0; cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + ">;", "java/lang/Object", new String[]{supDynName}); - {//构造方法 + {//Creator自身的构造方法 mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); @@ -199,36 +311,19 @@ public interface Creator { } {//create 方法 mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)L" + interName + ";", null, null); - ConstructorProperties cps = constructor.getAnnotation(ConstructorProperties.class); - String[] cparams = cps == null ? null : cps.value(); - if (cparams == null && constructor.getParameterCount() > 0) { // java 8 以上版本才支持的 -parameters 编译项 - Parameter[] params = constructor.getParameters(); - String[] ss = new String[params.length]; - for (int i = 0; i < ss.length; i++) { - try { - clazz.getDeclaredField(params[i].getName()); - } catch (Exception e) { //没有该字段,直接退出 - ss = null; - break; - } - ss[i] = params[i].getName(); - } - cparams = ss; - } - if (cparams != null) { + if (constructorParameters.length > 0) { av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorParameters.class), true); AnnotationVisitor av1 = av0.visitArray("value"); - for (String n : cparams) { - av1.visit(null, n); + for (SimpleEntry n : constructorParameters) { + av1.visit(null, n.getKey()); } av1.visitEnd(); av0.visitEnd(); } - final Class[] paramTypes = constructor.getParameterTypes(); final int[] iconsts = {ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5}; { //有Primitive数据类型且值为null的参数需要赋默认值 - for (int i = 0; i < paramTypes.length; i++) { - final Class pt = paramTypes[i]; + for (int i = 0; i < constructorParameters.length; i++) { + final Class pt = constructorParameters[i].getValue(); if (!pt.isPrimitive()) continue; mv.visitVarInsn(ALOAD, 1); if (i < 6) { @@ -277,7 +372,7 @@ public interface Creator { mv.visitInsn(DUP); //--------------------------------------- { - for (int i = 0; i < paramTypes.length; i++) { + for (int i = 0; i < constructorParameters.length; i++) { mv.visitVarInsn(ALOAD, 1); if (i < 6) { mv.visitInsn(iconsts[i]); @@ -285,7 +380,7 @@ public interface Creator { mv.visitIntInsn(BIPUSH, i); } mv.visitInsn(AALOAD); - final Class ct = paramTypes[i]; + final Class ct = constructorParameters[i].getValue(); if (ct.isPrimitive()) { final Class bigct = Array.get(Array.newInstance(ct, 1), 0).getClass(); mv.visitTypeInsn(CHECKCAST, bigct.getName().replace('.', '/')); @@ -303,7 +398,7 @@ public interface Creator { //--------------------------------------- mv.visitMethodInsn(INVOKESPECIAL, interName, "", Type.getConstructorDescriptor(constructor), false); mv.visitInsn(ARETURN); - mv.visitMaxs((paramTypes.length > 0 ? (paramTypes.length + 3) : 2), 2); + mv.visitMaxs((constructorParameters.length > 0 ? (constructorParameters.length + 3) : 2), 2); mv.visitEnd(); } { //虚拟 create 方法