package org.nutz.lang.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Comparator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.nutz.aop.DefaultClassDefiner; import org.nutz.lang.Mirror; import org.nutz.repo.org.objectweb.asm.ClassWriter; import org.nutz.repo.org.objectweb.asm.MethodVisitor; import org.nutz.repo.org.objectweb.asm.Opcodes; import org.nutz.repo.org.objectweb.asm.Type; public final class FastClassFactory implements Opcodes { private static AtomicInteger count = new AtomicInteger(); public static final String MethodArray_FieldName = "_$$Fast_methodArray"; public static final String ConstructorArray_FieldName = "_$$Fast_constructorArray"; public static final String SrcClass_FieldName = "_$$Fast_srcClass"; public static final String FieldNameArray_FieldName = "_$$Fast_fieldNames"; public static Map<String, FastClass> cache = new ConcurrentHashMap<String, FastClass>(); private static final Object lock = new Object(); public static FastClass get(Class<?> klass) { String cacheKey = klass.getName() + "_" + klass.getClassLoader(); FastClass fastClass = cache.get(cacheKey); if (fastClass != null) { return fastClass; } synchronized (lock) { fastClass = cache.get(cacheKey); if (fastClass != null) { return fastClass; } Class<?> fclass = create(klass); try { fastClass = (FastClass) fclass.newInstance(); cache.put(cacheKey, fastClass); return fastClass; } catch (Exception e) { throw new IllegalArgumentException("Fail to create FastClass for " + cacheKey, e); } } } protected static synchronized Class<?> create(Class<?> classZ) { String myName = classZ.getName().replace('.', '/') + FastClass.CLASSNAME + count.getAndIncrement(); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(V1_6, ACC_PUBLIC, myName, null, "org/nutz/lang/reflect/AbstractFastClass", null); // 添加默认构造方法 { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "org/nutz/lang/reflect/AbstractFastClass", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } // 添加默认字段 { cw.visitField(ACC_PUBLIC + ACC_STATIC, FastClassFactory.MethodArray_FieldName, "[Ljava/lang/reflect/Method;", null, null).visitEnd(); cw.visitField(ACC_PUBLIC + ACC_STATIC, ConstructorArray_FieldName, "[Ljava/lang/reflect/Constructor;", null, null).visitEnd(); cw.visitField(ACC_PUBLIC + ACC_STATIC, SrcClass_FieldName, "Ljava/lang/Class;", "Ljava/lang/Class<*>;", null).visitEnd(); } // 实现默认字段的getter { MethodVisitor mv = cw.visitMethod(ACC_PROTECTED, "getMethods", "()[Ljava/lang/reflect/Method;", null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, myName, FastClassFactory.MethodArray_FieldName, "[Ljava/lang/reflect/Method;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // ----------------------------------------------------------------------------------------------------- mv = cw.visitMethod(ACC_PROTECTED, "getConstructors", "()[Ljava/lang/reflect/Constructor;", "()[Ljava/lang/reflect/Constructor<*>;", null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, myName, ConstructorArray_FieldName, "[Ljava/lang/reflect/Constructor;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // ----------------------------------------------------------------------------------------------------- mv = cw.visitMethod(ACC_PROTECTED, "getSrcClass", "()Ljava/lang/Class;", "()Ljava/lang/Class<*>;", null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, myName, SrcClass_FieldName, "Ljava/lang/Class;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } Method[] methods = classZ.getMethods(); Arrays.sort(methods, new MethodComparator()); // 构建_invoke方法 { String[] methodNames = new String[methods.length]; String[] descs = new String[methods.length]; int[] modifies = new int[methods.length]; int[] invokeOps = new int[methods.length]; for (int i = 0; i < methods.length; i++) { methodNames[i] = methods[i].getName(); descs[i] = Type.getMethodDescriptor(methods[i]); modifies[i] = methods[i].getModifiers(); if (classZ.isInterface()) invokeOps[i] = INVOKEINTERFACE; else if (Modifier.isAbstract(methods[i].getModifiers())) invokeOps[i] = INVOKESPECIAL; else if (Modifier.isStatic(methods[i].getModifiers())) invokeOps[i] = INVOKESTATIC; else invokeOps[i] = INVOKEVIRTUAL; } FastClassAdpter.createInokeMethod(cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "_invoke", "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null), methodNames, descs, modifies, invokeOps, classZ.getName() .replace('.', '/')); } // 添加_born方法 Constructor<?>[] constructors = classZ.getConstructors(); Arrays.sort(constructors, new ConstructorComparator()); if (constructors.length > 0) { FastClassAdpter.createInokeConstructor(cw.visitMethod(ACC_PROTECTED + ACC_VARARGS, "_born", "(I[Ljava/lang/Object;)Ljava/lang/Object;", null, null), classZ.getName() .replace('.', '/'), constructors); } cw.visitEnd(); Class<?> xClass = DefaultClassDefiner.def(myName.replace('/', '.'), cw.toByteArray()); try { xClass.getField(SrcClass_FieldName).set(null, classZ); xClass.getField(MethodArray_FieldName).set(null, methods); xClass.getField(ConstructorArray_FieldName).set(null, constructors); } catch (Throwable e) { e.printStackTrace(); } return xClass; } // public static void main(String[] args) throws Throwable { // ASMifierClassVisitor.main(new String[]{"org.nutz.lang.reflect.XXX"}); // // // System.out.println(Type.getObjectType(AbstractFastClass.class.getName().replace('.', // // '/'))); // } } class Util { public static int compara(Class<?>[] mps1, Class<?>[] mps2) { if (mps1.length > mps2.length) return 1; if (mps1.length < mps2.length) return -1; for (int i = 0; i < mps1.length; i++) { if (mps1[i] == mps2[i]) continue; if (mps1[i].isPrimitive() && (!mps2[i].isPrimitive())) return -1; else if (mps2[i].isPrimitive() && (!mps1[i].isPrimitive())) return 1; if (mps1[i].isPrimitive() || mps2[i].isPrimitive()) if (Mirror.me(mps1[i]).getWrapper() == Mirror.me(mps2[i]) .getWrapper()) { if (mps1[i].isPrimitive()) return -1; else return 1; } if (mps2[i].isAssignableFrom(mps1[i])) return 1; } return 0; } } class ConstructorComparator implements Comparator<Constructor<?>> { public int compare(Constructor<?> c1, Constructor<?> c2) { if (c1 == c2) return 0; if (!c1.getName().equals(c2.getName())) return c1.getName().compareTo(c2.getName()); return Util.compara(c1.getParameterTypes(), c2.getParameterTypes()); } } class MethodComparator implements Comparator<Method> { public int compare(Method m1, Method m2) { if (m1 == m2) return 0; if (!m1.getName().equals(m2.getName())) return m1.getName().compareTo(m2.getName()); return Util.compara(m1.getParameterTypes(), m2.getParameterTypes()); } }