前言
CGLIB是一个强大的、高性能的代码生成库。其被广泛应用于AOP框架(Spring、dynaop)中,用以提供方法拦截操作。生成的代理类会继承被代理类,并重载其所有的方法。使用Cglib代理会生成三个代理类,继承目标类的代理类、继承FastClass的目标类、继承FastClss的代理类。
正文
我们要想了解其原理,先从生成的代理文件入手,看其结构特点。
测试用例
编写目标类(被代理类)
public class Book { public void read(){ System.out.println("read"); } }
自定义方法拦截器
public class MyCglib implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("增强"); Object o1 = methodProxy.invokeSuper(o, objects); return o1; } }
public class CglibTest { public static void main(String[] args) { //指定代理文件生成位置 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D:"); //通过Cglib Enhancer enhancer=new Enhancer(); //设置父类类型 enhancer.setSuperclass(Book.class); //设置回调接口 enhancer.setCallback(new MyCglib()); Book o = (Book) enhancer.create(); o.read(); } }
结果分析
运行以上测试用例后,查看生成的类目录,可以看到生成了3个.class字节码代理文件。
代理类:
import java.lang.reflect.Method; import org.springframework.cglib.core.ReflectUtils; import org.springframework.cglib.core.Signature; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Factory; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class Book$$EnhancerByCGLIB$$7c19c0f5 extends Book implements Factory { private boolean CGLIB$BOUND; public static Object CGLIB$FACTORY_DATA; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0; private static Object CGLIB$CALLBACK_FILTER; private static final Method CGLIB$read$0$Method; private static final MethodProxy CGLIB$read$0$Proxy; private static final Object[] CGLIB$emptyArgs; private static final Method CGLIB$equals$1$Method; private static final MethodProxy CGLIB$equals$1$Proxy; private static final Method CGLIB$toString$2$Method; private static final MethodProxy CGLIB$toString$2$Proxy; private static final Method CGLIB$hashCode$3$Method; private static final MethodProxy CGLIB$hashCode$3$Proxy; private static final Method CGLIB$clone$4$Method; private static final MethodProxy CGLIB$clone$4$Proxy; static void CGLIB$STATICHOOK1() { CGLIB$THREAD_CALLBACKS = new ThreadLocal(); CGLIB$emptyArgs = new Object[0]; Class var0 = Class.forName("proxy.cglib.Book$$EnhancerByCGLIB$$7c19c0f5"); Class var1; Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods()); CGLIB$equals$1$Method = var10000[0]; CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1"); CGLIB$toString$2$Method = var10000[1]; CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2"); CGLIB$hashCode$3$Method = var10000[2]; CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3"); CGLIB$clone$4$Method = var10000[3]; CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4"); CGLIB$read$0$Method = ReflectUtils.findMethods(new String[]{"read", "()V"}, (var1 = Class.forName("proxy.cglib.Book")).getDeclaredMethods())[0]; CGLIB$read$0$Proxy = MethodProxy.create(var1, var0, "()V", "read", "CGLIB$read$0"); } final void CGLIB$read$0() { super.read(); } public final void read() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } if (var10000 != null) { var10000.intercept(this, CGLIB$read$0$Method, CGLIB$emptyArgs, CGLIB$read$0$Proxy); } else { super.read(); } } final boolean CGLIB$equals$1(Object var1) { return super.equals(var1); } public final boolean equals(Object var1) { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } if (var10000 != null) { Object var2 = var10000.intercept(this, CGLIB$equals$1$Method, new Object[]{var1}, CGLIB$equals$1$Proxy); return var2 == null ? false : (Boolean)var2; } else { return super.equals(var1); } } final String CGLIB$toString$2() { return super.toString(); } public final String toString() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString(); } final int CGLIB$hashCode$3() { return super.hashCode(); } public final int hashCode() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } if (var10000 != null) { Object var1 = var10000.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy); return var1 == null ? 0 : ((Number)var1).intValue(); } else { return super.hashCode(); } } final Object CGLIB$clone$4() throws CloneNotSupportedException { return super.clone(); } protected final Object clone() throws CloneNotSupportedException { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } return var10000 != null ? var10000.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone(); } public static MethodProxy CGLIB$findMethodProxy(Signature var0) { String var10000 = var0.toString(); switch(var10000.hashCode()) { case -508378822: if (var10000.equals("clone()Ljava/lang/Object;")) { return CGLIB$clone$4$Proxy; } break; case 1080349215: if (var10000.equals("read()V")) { return CGLIB$read$0$Proxy; } break; case 1826985398: if (var10000.equals("equals(Ljava/lang/Object;)Z")) { return CGLIB$equals$1$Proxy; } break; case 1913648695: if (var10000.equals("toString()Ljava/lang/String;")) { return CGLIB$toString$2$Proxy; } break; case 1984935277: if (var10000.equals("hashCode()I")) { return CGLIB$hashCode$3$Proxy; } } return null; } public Book$$EnhancerByCGLIB$$7c19c0f5() { CGLIB$BIND_CALLBACKS(this); } public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) { CGLIB$THREAD_CALLBACKS.set(var0); } public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) { CGLIB$STATIC_CALLBACKS = var0; } private static final void CGLIB$BIND_CALLBACKS(Object var0) { Book$$EnhancerByCGLIB$$7c19c0f5 var1 = (Book$$EnhancerByCGLIB$$7c19c0f5)var0; if (!var1.CGLIB$BOUND) { var1.CGLIB$BOUND = true; Object var10000 = CGLIB$THREAD_CALLBACKS.get(); if (var10000 == null) { var10000 = CGLIB$STATIC_CALLBACKS; if (var10000 == null) { return; } } var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0]; } } public Object newInstance(Callback[] var1) { CGLIB$SET_THREAD_CALLBACKS(var1); Book$$EnhancerByCGLIB$$7c19c0f5 var10000 = new Book$$EnhancerByCGLIB$$7c19c0f5(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Callback var1) { CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1}); Book$$EnhancerByCGLIB$$7c19c0f5 var10000 = new Book$$EnhancerByCGLIB$$7c19c0f5(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) { CGLIB$SET_THREAD_CALLBACKS(var3); Book$$EnhancerByCGLIB$$7c19c0f5 var10000 = new Book$$EnhancerByCGLIB$$7c19c0f5; switch(var1.length) { case 0: var10000.<init>(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; default: throw new IllegalArgumentException("Constructor not found"); } } public Callback getCallback(int var1) { CGLIB$BIND_CALLBACKS(this); MethodInterceptor var10000; switch(var1) { case 0: var10000 = this.CGLIB$CALLBACK_0; break; default: var10000 = null; } return var10000; } public void setCallback(int var1, Callback var2) { switch(var1) { case 0: this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2; default: } } public Callback[] getCallbacks() { CGLIB$BIND_CALLBACKS(this); return new Callback[]{this.CGLIB$CALLBACK_0}; } public void setCallbacks(Callback[] var1) { this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0]; } static { CGLIB$STATICHOOK1(); } }
目标类FastClass:
import java.lang.reflect.InvocationTargetException; import org.springframework.cglib.core.Signature; import org.springframework.cglib.reflect.FastClass; public class Book$$FastClassByCGLIB$$236a9cb6 extends FastClass { public Book$$FastClassByCGLIB$$236a9cb6(Class var1) { super(var1); } public int getIndex(Signature var1) { String var10000 = var1.toString(); switch(var10000.hashCode()) { case 1080349215: if (var10000.equals("read()V")) { return 0; } break; case 1826985398: if (var10000.equals("equals(Ljava/lang/Object;)Z")) { return 1; } break; case 1913648695: if (var10000.equals("toString()Ljava/lang/String;")) { return 2; } break; case 1984935277: if (var10000.equals("hashCode()I")) { return 3; } } return -1; } public int getIndex(String var1, Class[] var2) { switch(var1.hashCode()) { case -1776922004: if (var1.equals("toString")) { switch(var2.length) { case 0: return 2; } } break; case -1295482945: if (var1.equals("equals")) { switch(var2.length) { case 1: if (var2[0].getName().equals("java.lang.Object")) { return 1; } } } break; case 3496342: if (var1.equals("read")) { switch(var2.length) { case 0: return 0; } } break; case 147696667: if (var1.equals("hashCode")) { switch(var2.length) { case 0: return 3; } } } return -1; } public int getIndex(Class[] var1) { switch(var1.length) { case 0: return 0; default: return -1; } } public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException { Book var10000 = (Book)var2; int var10001 = var1; try { switch(var10001) { case 0: var10000.read(); return null; case 1: return new Boolean(var10000.equals(var3[0])); case 2: return var10000.toString(); case 3: return new Integer(var10000.hashCode()); } } catch (Throwable var4) { throw new InvocationTargetException(var4); } throw new IllegalArgumentException("Cannot find matching method/constructor"); } public Object newInstance(int var1, Object[] var2) throws InvocationTargetException { Book var10000 = new Book; Book var10001 = var10000; int var10002 = var1; try { switch(var10002) { case 0: var10001.<init>(); return var10000; } } catch (Throwable var3) { throw new InvocationTargetException(var3); } throw new IllegalArgumentException("Cannot find matching method/constructor"); } public int getMaxIndex() { return 3; } }
1、我们可以看到代理类中拥有被代理类的所有的方法,在代理类被实例化后后执行静态代码块的内容,会对被代理类的每个方法进行解析,计算出代理类和被代理类方法名称的Signature值,并封装成MethodProxy对象;
创建MethodProxy过程见方法1详解
创建代理类过程见方法4详解
2、在代理类的方法里面会调用我们自定义的方法拦截器,并把代理类对象、方法名称解析对应的MethodProxy、方法对象传递进去,最终由自定义方法拦截器来调用。
3、自定义方法拦截器中的intercept方法,我们可以根据传递进来的MethodProxy决定调用逻辑,如MethodProxy的invokeSuper会调用父类方法。
4、MethodProxy的invokeSuper方法(见方法2详解)会传递代理类对象及其要执行对应方法参数。invokeSuper流程中会生成继承FastClass的被代理类跟代理类共两个.class文件。其中有两个重要的方法getIndex和invoke方法;
5、getIndex方法会根据步骤1中方法名计算出Signature来匹配方法对应的key,根据key去匹配invoke方法决定最终调用哪个方法。这个步骤没有涉及反射也是与JDK动态代理不同的地方。
方法1:MethodProxy类的create方法
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) { MethodProxy proxy = new MethodProxy(); //计算的是被代理类的 proxy.sig1 = new Signature(name1, desc); //计算的是代理类的 proxy.sig2 = new Signature(name2, desc); proxy.createInfo = new CreateInfo(c1, c2); return proxy; }
方法2:MethodProxy类的invoke方法
MethodProxy
public Object invokeSuper(Object obj, Object[] args) throws Throwable { try { //这个过程会创建类型为代理类跟被代理的FastClass类 init(); //获取init中封装好的信息 FastClassInfo fci = fastClassInfo; //调用被代理类的方法,传递方法index下标,通过该下标会在FastClass找出对应的方法并执行 return fci.f2.invoke(fci.i2, obj, args); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } catch (IllegalArgumentException ex) { if (fastClassInfo.i1 < 0) throw new IllegalArgumentException("Protected method: " + sig1); throw ex; } }
init(),见方法3详解
方法3:MethodProxy类的init方法
private void init() { /* * Using a volatile invariant allows us to initialize the FastClass and * method index pairs atomically. * * Double-checked locking is safe with volatile in Java 5. Before 1.5 this * code could allow fastClassInfo to be instantiated more than once, which * appears to be benign. */ if (fastClassInfo == null) { synchronized (initLock) { //判断是否缓存过 if (fastClassInfo == null) { CreateInfo ci = createInfo; FastClassInfo fci = new FastClassInfo(); //生成被代理类的FastClass对象 fci.f1 = helper(ci, ci.c1); //生成代理类的FastClass对象 fci.f2 = helper(ci, ci.c2); //根据sig值计算出该方法名在被代理类FastClass中对应的下标 fci.i1 = fci.f1.getIndex(sig1); //根据sig值计算出该方法名在代理类FastClass中对应的下标 fci.i2 = fci.f2.getIndex(sig2); fastClassInfo = fci; createInfo = null; } } } }
生成FastClass对象的过程跟生成代理类过程有点类似,这里不做讲解,后面会讲解代理类的创建过程,过程都差不多。
方法4:enhancer.create方法
代理类会在我们测试用例中调用enhancer.create()方法时进行创建。
public Object create() { classOnly = false; argumentTypes = null; return createHelper(); }
private Object createHelper() { //校验callbackTypes、filter是否为空,以及为空时的处理 preValidate(); //通过newInstance方法来创建EnhancerKey对象.KEY_FACTORY对象在测试用例new Enhance流程中会被动态代理创建 Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null, ReflectUtils.getNames(interfaces), filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter), callbackTypes, useFactory, interceptDuringConstruction, serialVersionUID); this.currentKey = key; //开始创建 Object result = super.create(key); return result; }
super.create(key),见方法5详解
方法5:create
protected Object create(Object key) { try { //获取类加载器 ClassLoader loader = getClassLoader(); //尝试从缓存中获取当前类加载器对应的ClassLoaderData对象 Map<ClassLoader, ClassLoaderData> cache = CACHE; ClassLoaderData data = cache.get(loader); //获取不到则创建 if (data == null) { synchronized (AbstractClassGenerator.class) { cache = CACHE; data = cache.get(loader); if (data == null) { //创建ClassLoaderData并加入newCache缓存中 Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache); data = new ClassLoaderData(loader); newCache.put(loader, data); CACHE = newCache; } } } this.key = key; //生成代理对象 Object obj = data.get(this, getUseCache()); //如果类似是Class对象,则进行实例化 if (obj instanceof Class) { return firstInstance((Class) obj); } return nextInstance(obj); } catch (RuntimeException | Error ex) { throw ex; } catch (Exception ex) { throw new CodeGenerationException(ex); } }
new ClassLoaderData(loader),见方法6详解
data.get(this, getUseCache()),见方法7详解
方法6:new ClassLoaderData(loader)
这个类比较长,这里我就把比较重要的两个方法进行讲解,这里
protected static class ClassLoaderData { private final Set<String> reservedClassNames = new HashSet<String>(); /** * {@link AbstractClassGenerator} here holds "cache key" (e.g. {@link org.springframework.cglib.proxy.Enhancer} * configuration), and the value is the generated class plus some additional values * (see {@link #unwrapCachedValue(Object)}. * <p>The generated classes can be reused as long as their classloader is reachable.</p> * <p>Note: the only way to access a class is to find it through generatedClasses cache, thus * the key should not expire as long as the class itself is alive (its classloader is alive).</p> */ private final LoadingCache<AbstractClassGenerator, Object, Object> generatedClasses; /** * Note: ClassLoaderData object is stored as a value of {@code WeakHashMap<ClassLoader, ...>} thus * this classLoader reference should be weak otherwise it would make classLoader strongly reachable * and alive forever. * Reference queue is not required since the cleanup is handled by {@link WeakHashMap}. */ private final WeakReference<ClassLoader> classLoader; private final Predicate uniqueNamePredicate = new Predicate() { public boolean evaluate(Object name) { return reservedClassNames.contains(name); } }; //这里存的是Function函数,后续步骤中会调用 private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() { public Object apply(AbstractClassGenerator gen) { return gen.key; } }; public ClassLoaderData(ClassLoader classLoader) { if (classLoader == null) { throw new IllegalArgumentException("classLoader == null is not yet supported"); } this.classLoader = new WeakReference<ClassLoader>(classLoader); //这里创建的是函数式接口,后续步骤中会调用 Function<AbstractClassGenerator, Object> load = new Function<AbstractClassGenerator, Object>() { //创建代理类 public Object apply(AbstractClassGenerator gen) { Class klass = gen.generate(ClassLoaderData.this); return gen.wrapCachedClass(klass); } }; generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load); } public ClassLoader getClassLoader() { return classLoader.get(); } public void reserveName(String name) { reservedClassNames.add(name); } public Predicate getUniqueNamePredicate() { return uniqueNamePredicate; } public Object get(AbstractClassGenerator gen, boolean useCache) { if (!useCache) { return gen.generate(ClassLoaderData.this); } else { Object cachedValue = generatedClasses.get(gen); return gen.unwrapCachedValue(cachedValue); } } }
方法7:get
public Object get(AbstractClassGenerator gen, boolean useCache) { //如果没有使用缓存,则直接调用创建代理类方法 if (!useCache) { return gen.generate(ClassLoaderData.this); } else { //这里会调用方法6中创建的两个Function函数式类 Object cachedValue = generatedClasses.get(gen); return gen.unwrapCachedValue(cachedValue); } }
public Object get(AbstractClassGenerator gen, boolean useCache) { //如果没有使用缓存,则直接调用创建代理类方法 if (!useCache) { return gen.generate(ClassLoaderData.this); } else { //这里会调用方法6中创建的两个Function函数式类 Object cachedValue = generatedClasses.get(gen); return gen.unwrapCachedValue(cachedValue); } }
this.createEntry(key, cacheKey, v),见方法8详解
方法8:createEntry
protected V createEntry(final K key, KK cacheKey, Object v) { boolean creator = false; FutureTask task; Object result; if (v != null) { task = (FutureTask)v; } else { //创建线程 task = new FutureTask(new Callable<V>() { public V call() throws Exception { //调用方法6中写好的Function函数 return LoadingCache.this.loader.apply(key); } }); //将线程加入缓存中 result = this.map.putIfAbsent(cacheKey, task); if (result == null) { creator = true; //开启线程 task.run(); } else { if (!(result instanceof FutureTask)) { return result; } task = (FutureTask)result; } } try { result = task.get(); } catch (InterruptedException var9) { throw new IllegalStateException("Interrupted while loading cache item", var9); } catch (ExecutionException var10) { Throwable cause = var10.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException)cause; } throw new IllegalStateException("Unable to load cache item", cause); } if (creator) { this.map.put(cacheKey, result); } return result; }
LoadingCache.this.loader.apply(key),见方法9详解
方法9:apply
调用函数式接口
public Object apply(AbstractClassGenerator gen) { Class klass = gen.generate(ClassLoaderData.this); return gen.wrapCachedClass(klass); }
protected Class generate(ClassLoaderData data) { validate(); //设置代理类名称前缀 if (superclass != null) { setNamePrefix(superclass.getName()); } else if (interfaces != null) { setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName()); } return super.generate(data); }
protected Class generate(ClassLoaderData data) { Class gen; Object save = CURRENT.get(); //将当前代理类生成器存入线程中 CURRENT.set(this); try { //获取类加载器 ClassLoader classLoader = data.getClassLoader(); if (classLoader == null) { throw new IllegalStateException("ClassLoader is null while trying to define class " + getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " + "Please file an issue at cglib's issue tracker."); } synchronized (classLoader) { //生成代理类名称 String name = generateClassName(data.getUniqueNamePredicate()); //缓存中存入这个名称 data.reserveName(name); //当前代理类设置了吗 this.setClassName(name); } if (attemptLoad) { try { //尝试使用类加载器获取代理对象,获取到则返回 gen = classLoader.loadClass(getClassName()); return gen; } catch (ClassNotFoundException e) { // ignore } } //生成代理类字节码流 byte[] b = strategy.generate(this); //获取字节码代表的代理类名称 String className = ClassNameReader.getClassName(new ClassReader(b)); ProtectionDomain protectionDomain = getProtectionDomain(); synchronized (classLoader) { // just in case // SPRING PATCH BEGIN gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass); // SPRING PATCH END } return gen; } catch (RuntimeException | Error ex) { throw ex; } catch (Exception ex) { throw new CodeGenerationException(ex); } finally { CURRENT.set(save); } }
strategy.generate(this),见方法10详解
方法10:generate
public byte[] generate(ClassGenerator cg) throws Exception { DebuggingClassWriter cw = this.getClassVisitor(); this.transform(cg).generateClass(cw); return this.transform(cw.toByteArray()); }
public void generateClass(ClassVisitor v) throws Exception { //如果目标类存在则以目标类为父类,否则以Object为父类 Class sc = (superclass == null) ? Object.class : superclass; if (TypeUtils.isFinal(sc.getModifiers())) throw new IllegalArgumentException("Cannot subclass final class " + sc.getName()); //获取父类的所有构造函数 List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors())); //去掉private不能被继承的构造函数 filterConstructors(sc, constructors); // Order is very important: must add superclass, then // its superclass chain, then each interface and // its superinterfaces. //存放代理类的所有方法 List actualMethods = new ArrayList(); List interfaceMethods = new ArrayList(); final Set forcePublic = new HashSet(); //获取其父类的所有方法,包括父类的父类... 父类的所有接口包含的方法,过滤掉不能被继承的方法 getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic); //所有方法进行修饰符处理 List methods = CollectionUtils.transform(actualMethods, new Transformer() { public Object transform(Object value) { Method method = (Method) value; int modifiers = Constants.ACC_FINAL | (method.getModifiers() & ~Constants.ACC_ABSTRACT & ~Constants.ACC_NATIVE & ~Constants.ACC_SYNCHRONIZED); if (forcePublic.contains(MethodWrapper.create(method))) { modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC; } return ReflectUtils.getMethodInfo(method, modifiers); } }); //创建写日期 ClassEmitter e = new ClassEmitter(v); if (currentData == null) { e.begin_class(Constants.V1_8, Constants.ACC_PUBLIC, getClassName(), Type.getType(sc), (useFactory ? TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) : TypeUtils.getTypes(interfaces)), Constants.SOURCE_FILE); } else { e.begin_class(Constants.V1_8, Constants.ACC_PUBLIC, getClassName(), null, new Type[]{FACTORY}, Constants.SOURCE_FILE); } List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance()); e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null); e.declare_field(Constants.ACC_PUBLIC | Constants.ACC_STATIC, FACTORY_DATA_FIELD, OBJECT_TYPE, null); if (!interceptDuringConstruction) { e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null); } e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null); e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null); if (serialVersionUID != null) { e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID); } for (int i = 0; i < callbackTypes.length; i++) { e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null); } // This is declared private to avoid "public field" pollution e.declare_field(Constants.ACC_PRIVATE | Constants.ACC_STATIC, CALLBACK_FILTER_FIELD, OBJECT_TYPE, null); if (currentData == null) { //写入方法 emitMethods(e, methods, actualMethods); //写入构造方法 emitConstructors(e, constructorInfo); } else { emitDefaultConstructor(e); } //写入回调方法 emitSetThreadCallbacks(e); //写入静态代理块 emitSetStaticCallbacks(e); //绑定回调方法 emitBindCallbacks(e); if (useFactory || currentData != null) { int[] keys = getCallbackKeys(); emitNewInstanceCallbacks(e); emitNewInstanceCallback(e); emitNewInstanceMultiarg(e, constructorInfo); emitGetCallback(e, keys); emitSetCallback(e, keys); emitGetCallbacks(e); emitSetCallbacks(e); } e.end_class(); }
到这里整个代理类创建过程就差不多告一段落了。
总结
Cglib动态代理不需要被代理类实现接口,根据原理我们知道生成的代理类是继承了被代理类,而且其方法调用方法是使用FastClass,这与JDK动态代理的反射有比较大的区别。
JDK和CGLIB动态代理的区别:
JDK代理使用的是反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGLIB代理使用字节码处理框架ASM,对代理对象类的class文件加载进来,通过修改字节码生成子类。
JDK创建代理对象效率较高,执行效率较低;
CGLIB创建代理对象效率较低,执行效率高。
JDK动态代理机制是委托机制,只能对实现接口的类生成代理,通过反射动态实现接口类;
CGLIB则使用的继承机制,针对类实现代理,被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,因为是继承机制,不- 能代理final修饰的类。
JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,需要满足以下要求:
1.实现InvocationHandler接口,重写invoke()
2.使用Proxy.newProxyInstance()产生代理对象
3.被代理的对象必须要实现接口
CGLib 必须依赖于CGLib的类库,需要满足以下要求:
1.实现MethodInterceptor接口,重写intercept()
2.使用Enhancer对象.create()产生代理对象