package org.nutz.lang.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.nutz.repo.org.objectweb.asm.Opcodes; import org.nutz.repo.org.objectweb.asm.Type; public final class FastClassFactory implements Opcodes { public static Map<String, FastClass> cache = new ConcurrentHashMap<String, FastClass>(); private static final Object lock = new Object(); protected static boolean useCache = true; public static boolean isUseCache() { return useCache; } public static void setUseCache(boolean useCache) { FastClassFactory.useCache = useCache; } public static void clearCache() { cache.clear(); FastMethodFactory.cache.clear(); } 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; } try { fastClass = create(klass); if (useCache) cache.put(cacheKey, fastClass); return fastClass; } catch (Exception e) { throw new IllegalArgumentException("Fail to create FastClass for " + cacheKey, e); } } } public static FastMethod get(Method method) { return get(method.getDeclaringClass()).fast(method); } public static FastMethod get(Constructor<?> constructor) { return get(constructor.getDeclaringClass()).fast(constructor); } protected static synchronized FastClass create(Class<?> klass) { Map<String, FastMethod> constructors = new HashMap<String, FastMethod>(); Map<String, FastMethod> methods = new HashMap<String, FastMethod>(); Map<String, FastMethod> fields = new HashMap<String, FastMethod>(); for (Constructor<?> constructor : klass.getConstructors()) { String key = Type.getConstructorDescriptor(constructor); FastMethod fm = FastMethodFactory.make(constructor); constructors.put(key, fm); } for (Method method : klass.getMethods()) { if (method.getName().contains("$")) continue; String key = method.getName() + "$" + Type.getMethodDescriptor(method); FastMethod fm = FastMethodFactory.make(method); methods.put(key, fm); } return new FastClassImpl(klass, constructors, methods, fields); } }