最近读了下cglib 的源代码,分析了cglib 通过字节码生成的代理类。就用cglib源代码包中的例子吧.
1.首先eclipse中开启debug模式,如图
例子的代码如下
public static void main(String args[]) { Bean bean = (Bean)newInstance(Bean.class); bean.addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { } } ); bean.setSampleProperty("TEST"); }
转入newInstance方法中
public static Object newInstance(Class clazz) { try { Beans interceptor = new Beans(); Enhancer e = new Enhancer(); e.setSuperclass(clazz); e.setCallback(interceptor); Object bean = e.create(); interceptor.propertySupport = new PropertyChangeSupport(bean); return bean; } catch (Throwable e) { e.printStackTrace(); throw new Error(e.getMessage()); } }
Enhancer 类中主要的几个配置参数,也是cglib代理的几个配置参数
( 1 )
private Class[] interfaces; private CallbackFilter filter; private Callback[] callbacks; private Type[] callbackTypes; private boolean classOnly; private Class superclass; private Class[] argumentTypes; private Object[] arguments; private boolean useFactory = true; private Long serialVersionUID; private boolean interceptDuringConstruction = true;
在Enhancer类中有个KEY_FACTORY的属性
private static final EnhancerKey KEY_FACTORY = (EnhancerKey) KeyFactory.create(EnhancerKey.class);
此行代码会自动生成 Enhancer 类的 内部接口 EnhancerKey 的实现类
public interface EnhancerKey { public Object newInstance( String type, String[] interfaces, CallbackFilter filter, Type[] callbackTypes, boolean useFactory, boolean interceptDuringConstruction, Long serialVersionUID ); }
反编译.class 文件的内容如下, 备注: 有些代码无法反编译,我参照.asm文件 重新改写了一下
package net.sf.cglib.proxy; import net.sf.cglib.core.KeyFactory; import org.objectweb.asm.Type; public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 extends KeyFactory implements Enhancer.EnhancerKey { private final String FIELD_0; private final String[] FIELD_1; private final CallbackFilter FIELD_2; private final Type[] FIELD_3; private final boolean FIELD_4; private final boolean FIELD_5; private final Long FIELD_6; public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72() { /** 以下在字节码指令中并没用赋值, 如果不赋值的话在eclipse的编译器中会报错,可能是final 字段在编译级别做了限制,在Jvm的指令中并没有啥实质的作用.*/ this.FIELD_0 = null; this.FIELD_1 = null; this.FIELD_2 = null; this.FIELD_3 = null; this.FIELD_4 = false; this.FIELD_5 = false; this.FIELD_6 = 0L; } public Object newInstance(String paramString, String[] paramArrayOfString, CallbackFilter paramCallbackFilter, Type[] paramArrayOfType, boolean paramBoolean1, boolean paramBoolean2, Long paramLong) { return new Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72(paramString, paramArrayOfString, paramCallbackFilter, paramArrayOfType, paramBoolean1, paramBoolean2, paramLong); } public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72(String paramString, String[] paramArrayOfString, CallbackFilter paramCallbackFilter, Type[] paramArrayOfType, boolean paramBoolean1, boolean paramBoolean2, Long paramLong) { this.FIELD_0 = paramString; this.FIELD_1 = paramArrayOfString; this.FIELD_2 = paramCallbackFilter; this.FIELD_3 = paramArrayOfType; this.FIELD_4 = paramBoolean1; this.FIELD_5 = paramBoolean2; this.FIELD_6 = paramLong; } public int hashCode() { // 根据 KeyFactory类的 PRIMES数组得来的 int result = 8095873; result += (FIELD_0 != null ? FIELD_0.hashCode() * 69403 : 0); if(FIELD_1 != null) { if(FIELD_1.length > 0) { String s0 = FIELD_1[0]; result += (s0.hashCode() * 69403); } } result += (FIELD_2 != null ? FIELD_2.hashCode() * 69403 : 0); if(FIELD_3 != null) { if(FIELD_3.length > 0) { Type t0 = FIELD_3[0]; result += t0.hashCode() * 69403; } } result += FIELD_4 ? 1 : 0; result += FIELD_5 ? 1 : 0; result += FIELD_6.hashCode() * 69403; return result; } public boolean equals(Object paramObject) { // 略 } public String toString() { // 略 } }在回到 Object bean = e.create();这行代码 , 之后会转到这
private Object createHelper() { validate(); if (superclass != null) { setNamePrefix(superclass.getName()); } else if (interfaces != null) { setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName()); } return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null, ReflectUtils.getNames(interfaces), filter, callbackTypes, useFactory, interceptDuringConstruction, serialVersionUID)); }KEY_FACTORY.newInstance 这创建一个 Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 这个对象的实例,
主要是作用是存储Enhancer 类的几个参数 上面 ( 1 )
之后转到 AbstractClassGenerator 类的create方法 如下代码
protected Object create(Object key) { try { Class gen = null; synchronized (source) { ClassLoader loader = getClassLoader(); ProtectionDomain protectionDomain = getProtectionDomain(); Map cache2 = null; cache2 = (Map) source.cache.get(loader); if (cache2 == null) { cache2 = new HashMap(); cache2.put(NAME_KEY, new HashSet()); source.cache.put(loader, cache2); } else if (useCache) { Reference ref = (Reference) cache2.get(key); gen = (Class) ((ref == null) ? null : ref.get()); } if (gen == null) { Object save = CURRENT.get(); CURRENT.set(this); try { this.key = key; if (attemptLoad) { try { gen = loader.loadClass(getClassName()); } catch (ClassNotFoundException e) { // ignore } } if (gen == null) { byte[] b = strategy.generate(this); String className = ClassNameReader.getClassName(new ClassReader(b)); getClassNameCache(loader).add(className); if (protectionDomain == null) { gen = ReflectUtils.defineClass(className, b, loader); } else { gen = ReflectUtils.defineClass(className, b, loader, protectionDomain); } } if (useCache) { cache2.put(key, new WeakReference(gen)); } return firstInstance(gen); } finally { CURRENT.set(save); } } } return firstInstance(gen); } catch (RuntimeException e) { throw e; } catch (Error e) { throw e; } catch (Exception e) { throw new CodeGenerationException(e); } }标红的代码 byte[] b = strategy.generate(this); 最终会转到 Enhancer 类的 generateClass方法 是创建代理的主要方法, 具体代码如下
public void generateClass(ClassVisitor v) throws Exception { // superclass 是要代理的类 Class sc = (superclass == null) ? Object.class : superclass; // 如果是 final 修饰的方法 抛出异常 if (TypeUtils.isFinal(sc.getModifiers())) throw new IllegalArgumentException("Cannot subclass final class " + sc.getName()); // 构造方法 List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors())); 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); } } ); // 以下是asm操作字节码 ClassEmitter e = new ClassEmitter(v); // useFactory => true // net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$a7ee9d2a e.begin_class( Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), Type.getType(sc), (useFactory ? TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) : TypeUtils.getTypes(interfaces)), Constants.SOURCE_FILE ); // [<init>()V] List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance()); e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null); // interceptDuringConstruction => true 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); } emitMethods(e, methods, actualMethods); emitConstructors(e, constructorInfo); emitSetThreadCallbacks(e); emitSetStaticCallbacks(e); emitBindCallbacks(e); if (useFactory) { int[] keys = getCallbackKeys(); emitNewInstanceCallbacks(e); emitNewInstanceCallback(e); emitNewInstanceMultiarg(e, constructorInfo); emitGetCallback(e, keys); emitSetCallback(e, keys); emitGetCallbacks(e); emitSetCallbacks(e); } e.end_class(); }主要 是获取代理类的所有方法 和 代理类所实现接口的所有方法 用字节码将 所有的方法写到一个代理的类中, 具体生成的class文件反编译之后如下: Bean$$EnhancerByCGLIB$$f51d20a3
package net.sf.cglib.samples; import java.beans.PropertyChangeListener; import java.lang.reflect.Method; import org.apache.tools.ant.taskdefs.Get; import net.sf.cglib.core.ReflectUtils; import net.sf.cglib.core.Signature; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class Bean$$EnhancerByCGLIB$$f51d20a3 extends Bean implements Factory { private boolean CGLIB$BOUND; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static /** final */Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0; private static final Method CGLIB$toString$0$Method; private static final MethodProxy CGLIB$toString$0$Proxy; private static final Object[] CGLIB$emptyArgs; private static final Method CGLIB$setSampleProperty$1$Method; private static final MethodProxy CGLIB$setSampleProperty$1$Proxy; private static final Method CGLIB$getSampleProperty$2$Method; private static final MethodProxy CGLIB$getSampleProperty$2$Proxy; private static final Method CGLIB$addPropertyChangeListener$3$Method; private static final MethodProxy CGLIB$addPropertyChangeListener$3$Proxy; private static final Method CGLIB$removePropertyChangeListener$4$Method; private static final MethodProxy CGLIB$removePropertyChangeListener$4$Proxy; private static final Method CGLIB$finalize$5$Method; private static final MethodProxy CGLIB$finalize$5$Proxy; private static final Method CGLIB$equals$6$Method; private static final MethodProxy CGLIB$equals$6$Proxy; private static final Method CGLIB$hashCode$7$Method; private static final MethodProxy CGLIB$hashCode$7$Proxy; private static final Method CGLIB$clone$8$Method; private static final MethodProxy CGLIB$clone$8$Proxy; static { // CGLIB$STATICHOOK1(); CGLIB$THREAD_CALLBACKS = new ThreadLocal(); CGLIB$emptyArgs = new Object[0]; Class localClass1 = null; try { localClass1 = Class.forName("net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Class localClass2 = null; Method[] tmp83_80 = null; try { tmp83_80 = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (localClass2 = Class.forName("java.lang.Object")).getDeclaredMethods()); } catch (SecurityException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } CGLIB$finalize$5$Method = tmp83_80[0]; CGLIB$finalize$5$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "finalize", "CGLIB$finalize$5"); Method[] tmp103_83 = tmp83_80; CGLIB$equals$6$Method = tmp103_83[1]; CGLIB$equals$6$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$6"); Method[] tmp123_103 = tmp103_83; CGLIB$hashCode$7$Method = tmp123_103[2]; CGLIB$hashCode$7$Proxy = MethodProxy.create(localClass2, localClass1, "()I", "hashCode", "CGLIB$hashCode$7"); Method[] tmp143_123 = tmp123_103; CGLIB$clone$8$Method = tmp143_123[3]; CGLIB$clone$8$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$8"); try { localClass2 = Class.forName("net.sf.cglib.samples.Bean"); } catch (ClassNotFoundException e) { } // tmp143_123; Method[] tmp236_233 = ReflectUtils.findMethods(new String[] { "toString", "()Ljava/lang/String;", "setSampleProperty", "(Ljava/lang/String;)V", "getSampleProperty", "()Ljava/lang/String;", "addPropertyChangeListener", "(Ljava/beans/PropertyChangeListener;)V", "removePropertyChangeListener", "(Ljava/beans/PropertyChangeListener;)V" }, localClass2.getDeclaredMethods() ); CGLIB$toString$0$Method = tmp236_233[0]; CGLIB$toString$0$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "toString", "CGLIB$toString$0"); Method[] tmp256_236 = tmp236_233; CGLIB$setSampleProperty$1$Method = tmp256_236[1]; CGLIB$setSampleProperty$1$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/String;)V", "setSampleProperty", "CGLIB$setSampleProperty$1"); Method[] tmp276_256 = tmp256_236; CGLIB$getSampleProperty$2$Method = tmp276_256[2]; CGLIB$getSampleProperty$2$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "getSampleProperty", "CGLIB$getSampleProperty$2"); Method[] tmp296_276 = tmp276_256; CGLIB$addPropertyChangeListener$3$Method = tmp296_276[3]; CGLIB$addPropertyChangeListener$3$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/beans/PropertyChangeListener;)V", "addPropertyChangeListener", "CGLIB$addPropertyChangeListener$3"); Method[] tmp316_296 = tmp296_276; CGLIB$removePropertyChangeListener$4$Method = tmp316_296[4]; CGLIB$removePropertyChangeListener$4$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/beans/PropertyChangeListener;)V", "removePropertyChangeListener", "CGLIB$removePropertyChangeListener$4"); // tmp316_296; } static void CGLIB$STATICHOOK1() { } final String CGLIB$toString$0() { return super.toString(); } public final String toString() { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0; if (tmp17_14 != null) { try { return (String)tmp17_14.intercept(this, CGLIB$toString$0$Method, CGLIB$emptyArgs, CGLIB$toString$0$Proxy); } catch (Throwable e) { } } return super.toString(); } final void CGLIB$setSampleProperty$1(String paramString) { super.setSampleProperty(paramString); } public final void setSampleProperty(String paramString) { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } if (this.CGLIB$CALLBACK_0 != null) { try { tmp4_1.intercept(this, CGLIB$setSampleProperty$1$Method, new Object[] {paramString}, CGLIB$setSampleProperty$1$Proxy); return; } catch (Throwable e) { } } super.setSampleProperty(paramString); } // CGLIB$emptyArgs final String CGLIB$getSampleProperty$2() { return super.getSampleProperty(); } public final String getSampleProperty() { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0; if (tmp17_14 != null) { try { return (String)tmp17_14.intercept(this, CGLIB$getSampleProperty$2$Method, CGLIB$emptyArgs, CGLIB$getSampleProperty$2$Proxy); } catch (Throwable e) { e.printStackTrace(); } } return super.getSampleProperty(); } final void CGLIB$addPropertyChangeListener$3(PropertyChangeListener paramPropertyChangeListener) { // compile error! superClass is abstract // super.addPropertyChangeListener(paramPropertyChangeListener); } public final void addPropertyChangeListener(PropertyChangeListener paramPropertyChangeListener) { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { // tmp4_1; CGLIB$BIND_CALLBACKS(this); } if (this.CGLIB$CALLBACK_0 != null) { try { tmp4_1.intercept(this, CGLIB$addPropertyChangeListener$3$Method, new Object[]{paramPropertyChangeListener}, CGLIB$addPropertyChangeListener$3$Proxy); return; } catch (Throwable e) { } } // compile error! superClass is abstract // super.addPropertyChangeListener(paramPropertyChangeListener); } final void CGLIB$removePropertyChangeListener$4(PropertyChangeListener paramPropertyChangeListener) { // compile error! superClass is abstract // super.removePropertyChangeListener(paramPropertyChangeListener); } public final void removePropertyChangeListener(PropertyChangeListener paramPropertyChangeListener) { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { // tmp4_1; CGLIB$BIND_CALLBACKS(this); } if (this.CGLIB$CALLBACK_0 != null) { try { tmp4_1.intercept(this, CGLIB$removePropertyChangeListener$4$Method, new Object[]{paramPropertyChangeListener}, CGLIB$removePropertyChangeListener$4$Proxy); return; } catch (Throwable e) { } } // super.removePropertyChangeListener(paramPropertyChangeListener); } final void CGLIB$finalize$5() throws Throwable { super.finalize(); } protected final void finalize() throws Throwable { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } if (this.CGLIB$CALLBACK_0 != null) { tmp4_1.intercept(this, CGLIB$finalize$5$Method, CGLIB$emptyArgs, CGLIB$finalize$5$Proxy); return; } super.finalize(); } final boolean CGLIB$equals$6(Object paramObject) { return super.equals(paramObject); } public final boolean equals(Object paramObject) { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { // tmp4_1; CGLIB$BIND_CALLBACKS(this); } MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0; if (tmp17_14 != null) { Object tmp41_36; try { tmp41_36 = tmp17_14.intercept(this, CGLIB$equals$6$Method, new Object[] { paramObject }, CGLIB$equals$6$Proxy); return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue(); } catch (Throwable e) { e.printStackTrace(); } } return super.equals(paramObject); } final int CGLIB$hashCode$7() { return super.hashCode(); } public final int hashCode() { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0; if (tmp17_14 != null) { Object tmp36_31; try { tmp36_31 = tmp17_14.intercept(this, CGLIB$hashCode$7$Method, CGLIB$emptyArgs, CGLIB$hashCode$7$Proxy); return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue(); } catch (Throwable e) { } } return super.hashCode(); } final Object CGLIB$clone$8() throws CloneNotSupportedException { return super.clone(); } protected final Object clone() throws CloneNotSupportedException { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0; if (tmp17_14 != null) { try { return tmp17_14.intercept(this, CGLIB$clone$8$Method, CGLIB$emptyArgs, CGLIB$clone$8$Proxy); } catch (Throwable e) { // e.printStackTrace(); return null; } } return super.clone(); } public static MethodProxy CGLIB$findMethodProxy(Signature paramSignature) { String tmp4_1 = paramSignature.toString(); switch (tmp4_1.hashCode()) { case -1574182249: if (tmp4_1.equals("finalize()V")) return CGLIB$finalize$5$Proxy; break; case -1148146316: if(tmp4_1.equals("addPropertyChangeListener(Ljava/beans/PropertyChangeListener;)V")) return CGLIB$addPropertyChangeListener$3$Proxy; case -727109664: if(tmp4_1.equals("getSampleProperty()Ljava/lang/String;")) return CGLIB$getSampleProperty$2$Proxy; case -508378822: if(tmp4_1.equals("clone()Ljava/lang/Object;")) return CGLIB$clone$8$Proxy; case -182669826: if(tmp4_1.equals("setSampleProperty(Ljava/lang/String;)V")) return CGLIB$setSampleProperty$1$Proxy; case -112787753: if(tmp4_1.equals("removePropertyChangeListener(Ljava/beans/PropertyChangeListener;)V")) return CGLIB$removePropertyChangeListener$4$Proxy; case 1826985398: if(tmp4_1.equals("equals(Ljava/lang/Object;)Z")) return CGLIB$equals$6$Proxy; case 1913648695: if(tmp4_1.equals("toString()Ljava/lang/String;")) return CGLIB$toString$0$Proxy; case 1984935277: if(tmp4_1.equals("hashCode()I")) return CGLIB$hashCode$7$Proxy; default: return CGLIB$finalize$5$Proxy; } return null; } public Bean$$EnhancerByCGLIB$$f51d20a3() { CGLIB$BIND_CALLBACKS(this); } public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback); } public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$STATIC_CALLBACKS = paramArrayOfCallback; } private static final void CGLIB$BIND_CALLBACKS(Object paramObject) { if(paramObject instanceof Bean$$EnhancerByCGLIB$$f51d20a3) { Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject; if(f51d20a3.CGLIB$BOUND) { return; } f51d20a3.CGLIB$BOUND = true; Object obj = CGLIB$THREAD_CALLBACKS.get(); if(obj != null) { Callback[] callbacks = (Callback[])obj; MethodInterceptor interceptor = (MethodInterceptor)callbacks[0]; f51d20a3.CGLIB$CALLBACK_0 = interceptor; return; } if(CGLIB$STATIC_CALLBACKS != null) f51d20a3.CGLIB$CALLBACK_0 = (MethodInterceptor)CGLIB$STATIC_CALLBACKS[0]; } } public Object newInstance(Callback[] paramArrayOfCallback) { CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback); Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = new Bean$$EnhancerByCGLIB$$f51d20a3(); CGLIB$SET_THREAD_CALLBACKS(null); return f51d20a3; } public Object newInstance(Callback paramCallback) { CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback }); Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = new Bean$$EnhancerByCGLIB$$f51d20a3(); CGLIB$SET_THREAD_CALLBACKS(null); return f51d20a3; } public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback) { CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback); Class[] tmp9_8 = paramArrayOfClass; Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = null; switch (tmp9_8.length) { case 0: f51d20a3 = new Bean$$EnhancerByCGLIB$$f51d20a3(); break; default: throw new IllegalArgumentException("Constructor not found"); } CGLIB$SET_THREAD_CALLBACKS(null); return f51d20a3; } public Callback getCallback(int paramInt) { CGLIB$BIND_CALLBACKS(this); switch (paramInt) { case 0: break; } return null; } public void setCallback(int paramInt, Callback paramCallback) { switch (paramInt) { case 0: this.CGLIB$CALLBACK_0 = ((MethodInterceptor) paramCallback); break; } } public Callback[] getCallbacks() { CGLIB$BIND_CALLBACKS(this); return new Callback[] { this.CGLIB$CALLBACK_0 }; } public void setCallbacks(Callback[] paramArrayOfCallback) { this.CGLIB$CALLBACK_0 = ((MethodInterceptor) paramArrayOfCallback[0]); } }再回到 AbstractClassGenerator 类中 的create 方法中 ,最后有个 firstInstance方法的调用
protected Object firstInstance(Class type) throws Exception { if (classOnly) { return type; } else { return createUsingReflection(type); } }看 createUsingReflection 方法
private Object createUsingReflection(Class type) { setThreadCallbacks(type, callbacks); try { if (argumentTypes != null) { return ReflectUtils.newInstance(type, argumentTypes, arguments); } else { return ReflectUtils.newInstance(type); } } finally { // clear thread callbacks to allow them to be gc'd setThreadCallbacks(type, null); } }再看 setThreadCallbacks(type, callbacks);
private static void setThreadCallbacks(Class type, Callback[] callbacks) { setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);// CGLIB$SET_THREAD_CALLBACKS }
private static void setCallbacksHelper(Class type, Callback[] callbacks, String methodName) { // TODO: optimize try { Method setter = getCallbacksSetter(type, methodName); setter.invoke(null, new Object[] { callbacks }); } catch (NoSuchMethodException e) { throw new IllegalArgumentException(type + " is not an enhanced class"); } catch (IllegalAccessException e) { throw new CodeGenerationException(e); } catch (InvocationTargetException e) { throw new CodeGenerationException(e); } }主要是反射 Bean$$EnhancerByCGLIB$$f51d20a3 类 中 的静态CGLIB$SET_THREAD_CALLBACKS方法
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback); }将 MethodInterceptor 接口的实现类 注入到ThreadLocal 中, 主要作用是 代理类在 进行实际调用方法之前先调用 MethodInterceptor 接口的intercept方法, 本例子中就是 Beans 类, public class Beans implements MethodInterceptor 接下来 是通过反射设立一个 Bean$$EnhancerByCGLIB$$f51d20a3 对象, 查看 Bean$$EnhancerByCGLIB$$f51d20a3 类的构造方法
public Bean$$EnhancerByCGLIB$$f51d20a3() { CGLIB$BIND_CALLBACKS(this); }
private static final void CGLIB$BIND_CALLBACKS(Object paramObject) { if(paramObject instanceof Bean$$EnhancerByCGLIB$$f51d20a3) { Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject; if(f51d20a3.CGLIB$BOUND) { return; } f51d20a3.CGLIB$BOUND = true; Object obj = CGLIB$THREAD_CALLBACKS.get(); if(obj != null) { Callback[] callbacks = (Callback[])obj; MethodInterceptor interceptor = (MethodInterceptor)callbacks[0]; f51d20a3.CGLIB$CALLBACK_0 = interceptor; return; } if(CGLIB$STATIC_CALLBACKS != null) f51d20a3.CGLIB$CALLBACK_0 = (MethodInterceptor)CGLIB$STATIC_CALLBACKS[0]; } }以上代码主要是为代理类Bean$$EnhancerByCGLIB$$f51d20a3类中的 属性 private MethodInterceptor CGLIB$CALLBACK_0; 进行赋值,也就是 为代理类注册 拦截器( MethodInterceptor )的方法 此时 Bean$$EnhancerByCGLIB$$f51d20a3 实例化完成 再回到例子代码中 bean.setSampleProperty("TEST"); 调用代理类的 setSampleProperty Bean$$EnhancerByCGLIB$$f51d20a3类的 setSampleProperty方法如下:
public final void setSampleProperty(String paramString) { MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0; if (tmp4_1 == null) { CGLIB$BIND_CALLBACKS(this); } if (this.CGLIB$CALLBACK_0 != null) { try { tmp4_1.intercept(this, CGLIB$setSampleProperty$1$Method, new Object[] {paramString}, CGLIB$setSampleProperty$1$Proxy); return; } catch (Throwable e) { } } super.setSampleProperty(paramString); }以上代码先 回调 拦截器(MethodInterceptor) intercept 方法, 此时 代码转回 Beans类的 intercept 方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object retValFromSuper = null; try { if (!Modifier.isAbstract(method.getModifiers())) { retValFromSuper = proxy.invokeSuper(obj, args); } } finally { String name = method.getName(); if( name.equals("addPropertyChangeListener")) { addPropertyChangeListener((PropertyChangeListener)args[0]); } else if ( name.equals( "removePropertyChangeListener" ) ){ removePropertyChangeListener((PropertyChangeListener)args[0]); } if( name.startsWith("set") && args.length == 1 && method.getReturnType() == Void.TYPE ){ char propName[] = name.substring("set".length()).toCharArray(); propName[0] = Character.toLowerCase( propName[0] ); propertySupport.firePropertyChange( new String( propName ) , null , args[0]); } } return retValFromSuper; }intercept方法的第4个参数的来源于代理类 Bean$$EnhancerByCGLIB$$f51d20a3 类的初始化静态方法 static {}
CGLIB$getSampleProperty$2$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "getSampleProperty", "CGLIB$getSampleProperty$2");接下来转到 retValFromSuper = proxy.invokeSuper(obj, args); MethodProxy类
public Object invokeSuper(Object obj, Object[] args) throws Throwable { try { init(); FastClassInfo fci = fastClassInfo; return fci.f2.invoke(fci.i2, obj, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } }再看 init(); 方法
private void init() { if (fastClassInfo == null) { synchronized (initLock) { if (fastClassInfo == null) { CreateInfo ci = createInfo; FastClassInfo fci = new FastClassInfo(); fci.f1 = helper(ci, ci.c1);// class net.sf.cglib.samples.Bean fci.f2 = helper(ci, ci.c2);// class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3 fci.i1 = fci.f1.getIndex(sig1);// setSampleProperty(Ljava/lang/String;)V class net.sf.cglib.samples.Bean fci.i2 = fci.f2.getIndex(sig2);// CGLIB$setSampleProperty$1(Ljava/lang/String;)V class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3 fastClassInfo = fci; createInfo = null; } } } }fci.f1 = helper(ci, ci.c1);// class net.sf.cglib.samples.Bean
private static FastClass helper(CreateInfo ci, Class type) { FastClass.Generator g = new FastClass.Generator(); g.setType(type);// class net.sf.cglib.samples.Bean class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$23fe786a g.setClassLoader(ci.c2.getClassLoader()); g.setNamingPolicy(ci.namingPolicy); g.setStrategy(ci.strategy); g.setAttemptLoad(ci.attemptLoad); return g.create(); }最终会转到 FastClass类的 generateClass方法
public void generateClass(ClassVisitor v) throws Exception { new FastClassEmitter(v, getClassName(), type); }fci.f2 = helper(ci, ci.c2);// class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3 以上2行代码 会动态的 创建2个继承 FastClass 的类 一个是 Bean$$FastClassByCGLIB$$f4d01dac 主要是包装 net.sf.cglib.samples.Bean 类 另一个Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c 主要是包装 net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3(代理类) 具体反编译的代码如下 Bean$$FastClassByCGLIB$$f4d01dac
package net.sf.cglib.samples; import java.beans.PropertyChangeListener; import java.lang.reflect.InvocationTargetException; import net.sf.cglib.core.Signature; import net.sf.cglib.reflect.FastClass; public class Bean$$FastClassByCGLIB$$f4d01dac extends FastClass { public Bean$$FastClassByCGLIB$$f4d01dac(Class paramClass) { super(paramClass); } public int getIndex(Signature paramSignature) { String tmp4_1 = paramSignature.toString(); switch (tmp4_1.hashCode()) { case -1725733088: if (tmp4_1.equals("getClass()Ljava/lang/Class;")) return 10; break; case -1148146316: if(tmp4_1.equals("addPropertyChangeListener(Ljava/beans/PropertyChangeListener;)V")) return 3; case -1026001249: if(tmp4_1.equals("wait(JI)V")) return 6; case -727109664: if(tmp4_1.equals("getSampleProperty()Ljava/lang/String;")) return 2; case -182669826: case -112787753: case 243996900: case 946854621: case 1116248544: case 1826985398: case 1902039948: case 1913648695: case 1984935277: } return -1; } public int getIndex(String paramString, Class[] paramArrayOfClass) { String tmp3_0 = paramString; switch (tmp3_0.hashCode()) { case -2043397483: if (tmp3_0.equals("getSampleProperty")) { Class[] tmp112_1 = paramArrayOfClass; switch (tmp112_1.length) { case 0: return 2; default: } } break; case -1776922004: case -1645115555: case -1295482945: case -1117363270: case -1039689911: case 3641717: case 147696667: case 1311416993: case 1902066072: case 1950568386: } return -1; } public int getIndex(Class[] paramArrayOfClass) { Class[] tmp1_0 = paramArrayOfClass; switch (tmp1_0.length) { case 0: return 0; default: } return -1; } public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject) throws InvocationTargetException { try { Bean bean = (Bean)paramObject; switch(paramInt) { case 0: return bean.toString(); case 1: bean.setSampleProperty((String)paramArrayOfObject[0]); return null; case 2: return bean.getSampleProperty(); case 3: bean.addPropertyChangeListener((PropertyChangeListener)paramArrayOfObject[0]); return null; case 4: bean.removePropertyChangeListener((PropertyChangeListener)paramArrayOfObject[0]); return null; case 5: bean.wait(); return null; case 6: bean.wait(((Number)paramArrayOfObject[0]).longValue(), (int)paramArrayOfObject[1]); return null; case 7: bean.wait(((Number)paramArrayOfObject[0]).longValue()); return null; case 8: return bean.equals(paramArrayOfObject[0]); case 9: return bean.hashCode(); case 10: return bean.getClass(); case 11: bean.notify(); return null; case 12: bean.notifyAll(); return null; default: } } catch(Throwable ex) { throw new InvocationTargetException(ex); } throw new IllegalArgumentException("Cannot find matching method/constructor"); } public Object newInstance(int paramInt, Object[] paramArrayOfObject) throws InvocationTargetException { try { switch (paramInt) { case 0: return new Bean() { public void removePropertyChangeListener(PropertyChangeListener listener) { } public void addPropertyChangeListener(PropertyChangeListener listener) { } }; default: } } catch (Throwable localThrowable) { throw new InvocationTargetException(localThrowable); } throw new IllegalArgumentException("Cannot find matching method/constructor"); } public int getMaxIndex() { return 12; } }Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c 类
package net.sf.cglib.samples; import java.lang.reflect.InvocationTargetException; import net.sf.cglib.core.Signature; import net.sf.cglib.proxy.Callback; import net.sf.cglib.reflect.FastClass; public class Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c extends FastClass { public Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c(Class paramClass) { super(paramClass); } public int getIndex(Signature paramSignature) { String tmp4_1 = paramSignature.toString(); switch (tmp4_1.hashCode()) { case -2055565910: if (tmp4_1.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) return 17; break; case -1725733088: if(tmp4_1.equals("getClass()Ljava/lang/Class;")) { return 32; } break; case -1682551285: if(tmp4_1.equals("CGLIB$getSampleProperty$2()Ljava/lang/String;")) { return 20; } break; case -1649069589: if(tmp4_1.equals("CGLIB$clone$8()Ljava/lang/Object;")) { return 26; } break; case -1574182249: case -1457535688: case -1411723561: case -1184739478: case -1148146316: case -1026001249: case -894172689: case -727109664: case -623122092: case -508378822: case -419626537: case -182669826: case -112787753: case 243996900: case 246779284: case 560567118: case 687209440: case 811063227: case 812055105: case 883767110: case 946854621: case 973717575: case 1116248544: case 1221173700: case 1230699260: case 1365196803: case 1584330438: case 1826985398: case 1902039948: case 1913648695: case 1984935277: } return 2; } public int getIndex(String paramString, Class[] paramArrayOfClass) { String tmp3_0 = paramString; switch (tmp3_0.hashCode()) { case -2083498446: if (tmp3_0.equals("CGLIB$finalize$5")) { Class[] tmp272_1 = paramArrayOfClass; switch (tmp272_1.length) { case 0: return 23; default: } } break; case -2043397483: if(tmp3_0.equals("getSampleProperty")) { Class[] tmp272_1 = paramArrayOfClass; switch (tmp272_1.length) { case 0: return 13; default: } } case -1776922004: case -1668635866: case -1645115555: case -1295482945: case -1117363270: case -1053468136: case -1039689911: case -681255906: case -277508560: case -124978604: case -60403779: case -29025551: case 3641717: case 85179481: case 94756189: case 147696667: case 161998109: case 495524492: case 539783499: case 1154623345: case 1311416993: case 1543336187: case 1811874389: case 1817099975: case 1902066072: case 1905679803: case 1950568386: case 1951977614: case 2083511360: } return 2; } public int getIndex(Class[] paramArrayOfClass) { Class[] tmp1_0 = paramArrayOfClass; switch (tmp1_0.length) { case 0: return 0; default: } return 2; } public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject) throws InvocationTargetException { try { if(paramObject instanceof net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3) { Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject; switch(paramInt) { case 0: f51d20a3.CGLIB$finalize$5(); return null; case 1: return f51d20a3.CGLIB$equals$6(paramArrayOfObject[0]); case 2: return f51d20a3.CGLIB$toString$0(); case 3: return f51d20a3.CGLIB$hashCode$7(); case 4: return f51d20a3.CGLIB$clone$8(); case 5: return f51d20a3.newInstance((java.lang.Class[])paramArrayOfObject[0], (java.lang.Object[])paramArrayOfObject[1], (net.sf.cglib.proxy.Callback[])paramArrayOfObject[2]); case 6: return f51d20a3.newInstance((net.sf.cglib.proxy.Callback)paramArrayOfObject[0]); case 7: return f51d20a3.newInstance((net.sf.cglib.proxy.Callback[])paramArrayOfObject[0]); case 8: f51d20a3.setCallback(((Number)paramArrayOfObject[0]).intValue(), (Callback)paramArrayOfObject[1]); return null; case 9: return f51d20a3.getCallback(((Number)paramArrayOfObject[0]).intValue()); case 10: f51d20a3.setCallbacks((Callback[])paramArrayOfObject[0]); return null; // 下面省略N个方法 } } } catch(Throwable ex) { throw new InvocationTargetException(ex); } throw new IllegalArgumentException("Cannot find matching method/constructor"); } public Object newInstance(int paramInt, Object[] paramArrayOfObject) throws InvocationTargetException { try { switch (paramInt) { case 0: return new Bean$$EnhancerByCGLIB$$f51d20a3(); } } catch (Throwable localThrowable) { throw new InvocationTargetException(localThrowable); } throw new IllegalArgumentException("Cannot find matching method/constructor"); } public int getMaxIndex() { return 34; } }之后再转到 MethodProxy类中的 invokeSuper 方法中
public Object invokeSuper(Object obj, Object[] args) throws Throwable { try { init(); FastClassInfo fci = fastClassInfo; return fci.f2.invoke(fci.i2, obj, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } }return fci.f2.invoke(fci.i2, obj, args); 再看 Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c 类的invoke方法
public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject) throws InvocationTargetException { try { if(paramObject instanceof net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3) { Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject; switch(paramInt) { case 0: f51d20a3.CGLIB$finalize$5(); return null; case 1: return f51d20a3.CGLIB$equals$6(paramArrayOfObject[0]); case 2: return f51d20a3.CGLIB$toString$0(); case 3: return f51d20a3.CGLIB$hashCode$7(); case 4: return f51d20a3.CGLIB$clone$8(); case 5: return f51d20a3.newInstance((java.lang.Class[])paramArrayOfObject[0], (java.lang.Object[])paramArrayOfObject[1], (net.sf.cglib.proxy.Callback[])paramArrayOfObject[2]); case 6: return f51d20a3.newInstance((net.sf.cglib.proxy.Callback)paramArrayOfObject[0]); case 7: return f51d20a3.newInstance((net.sf.cglib.proxy.Callback[])paramArrayOfObject[0]); case 8: f51d20a3.setCallback(((Number)paramArrayOfObject[0]).intValue(), (Callback)paramArrayOfObject[1]); return null; case 9: return f51d20a3.getCallback(((Number)paramArrayOfObject[0]).intValue()); case 10: f51d20a3.setCallbacks((Callback[])paramArrayOfObject[0]); return null; // 下面省略N个方法 } } } catch(Throwable ex) { throw new InvocationTargetException(ex); } throw new IllegalArgumentException("Cannot find matching method/constructor"); }在以上的方法中会调到 代理类 Bean$$EnhancerByCGLIB$$f51d20a3 的 CGLIB$setSampleProperty$1 方法
final void CGLIB$setSampleProperty$1(String paramString) { super.setSampleProperty(paramString); }因为 Bean$$EnhancerByCGLIB$$f51d20a3 代理类继承 Bean 类 所以 super.setSampleProperty(paramString); 在调用 Bean 类中的 setSampleProperty方法 到此为止整个代理的过程就结束了. 总结 cglib和JDK 的动态代理区别 cglib 既可以代理类,也可以代理接口, cglib 在代理类时 要继承 目标的类 , jdk的动态代理只能代理接口. 只能实现目标的接口 通俗一点说原理吧, JDK 只能代理接口是因为 它只反射出接口中的所有方法, 然后将所有的方法写到一个新的class文件中,既代理的类,再用native的类的加载器进行加载。 而cglib 代理类, 是反射本类中的所有方法和接口中的所有方法 , 再用类加载加载Class 文件, cglib 类加载器获取的方式是通过反射
private static Method DEFINE_CLASS; private static final ProtectionDomain PROTECTION_DOMAIN;
static { PROTECTION_DOMAIN = getProtectionDomain(ReflectUtils.class); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { Class loader = Class.forName("java.lang.ClassLoader"); // JVM crash w/o this DEFINE_CLASS = loader.getDeclaredMethod( "defineClass", new Class[] { String.class, byte[].class, Integer.TYPE, Integer.TYPE, ProtectionDomain.class } ); DEFINE_CLASS.setAccessible(true); } catch (ClassNotFoundException e) { throw new CodeGenerationException(e); } catch (NoSuchMethodException e) { throw new CodeGenerationException(e); } return null; } }); }
public static ProtectionDomain getProtectionDomain(final Class source) { if(source == null) { return null; } return (ProtectionDomain)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return source.getProtectionDomain(); } }); }======= 之前写了一次很详细的过程, 不知怎么回事没保存就闪退了,没保存上, 又写了第二遍, 没有之前的那次写的详细了,/(ㄒoㄒ)/~~. 最后附上完成的工程,有想看的朋友可以下载, 以上有些代码无法反编译,是我自己读asm文件翻转成Java代码的,不一定会100%的准确, 但大致的思路是对的, 如有错误也请大家纠正,谢谢.