Cglib代理原理剖析

package Cglib第三方代理;
 
import java.lang.reflect.Method;
 
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
 
public class DynamicProxy implements MethodInterceptor {
 
    //真实对象
    Object targetObject;
    
    public Object getProxyObject(Object object){
        this.targetObject = object;
        //增强器,动态代码生成器
        Enhancer enhancer = new Enhancer();
        //回调方法
        enhancer.setCallback(this);
        //设置生成类的父类类型
        enhancer.setSuperclass(targetObject.getClass());
        //动态生成字节码并返回代理对象
        return enhancer.create();
    }
    
    //拦截方法
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("Hello,I am the weaved method before");
        
        Object result = methodProxy.invoke(targetObject,args);
        
        System.out.println("Hello,I am the weaved method after");
 
        return result;
    }
 
}
class RealClass{
    public void hah(){
        System.out.println("我是真实类要处理的东东,也叫切入点,快来增强我");
    }
}
package Cglib第三方代理;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import org.junit.Test;
 
import net.sf.cglib.core.DebuggingClassWriter;
import sun.misc.ProxyGenerator;
 
public class TestCglibMain {
	
//	RealClass realObject = (RealClass) new DynamicProxy().getProxyObject(new RealClass());
//	@Test
//	public void test() throws IOException{
//		realObject.hah();
		//System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "H:\\Hadoop_eclipse\\eclipse-jee-mars-2-win32-x86_64\\剑指Offer\\反射详解\\bin\\cgliballclass");
		
		
//		String path = "H:/Hadoop_eclipse/eclipse-jee-mars-2-win32-x86_64/剑指Offer/反射详解/bin/cgliballclass/$proxy1.class";
//		byte[] classFile = //new byte[1024]; 
//				ProxyGenerator.generateProxyClass("$Proxy1",
//						realObject.getClass().getClasses());
//        FileOutputStream out = null;
//
//        try {
//            out = new FileOutputStream(path);
//            out.write(classFile);
//            out.flush();
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                out.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
			
		
		
//	}
	public static void main(String[] args) throws IOException {
		RealClass realObject = (RealClass) new DynamicProxy().getProxyObject(new RealClass());
		realObject.hah();
		//System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "H:\\Hadoop_eclipse\\eclipse-jee-mars-2-win32-x86_64\\剑指Offer\\反射详解\\bin\\cgliballclass");
		System.in.read();
	}
}
package Cglib第三方代理;

import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
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 RealClass$$EnhancerByCGLIB$$afcc55ac
  extends RealClass
  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$hah$0$Method;
  private static final MethodProxy CGLIB$hah$0$Proxy;
  private static final Object[] CGLIB$emptyArgs;
  private static final Method CGLIB$finalize$1$Method;
  private static final MethodProxy CGLIB$finalize$1$Proxy;
  private static final Method CGLIB$equals$2$Method;
  private static final MethodProxy CGLIB$equals$2$Proxy;
  private static final Method CGLIB$toString$3$Method;
  private static final MethodProxy CGLIB$toString$3$Proxy;
  private static final Method CGLIB$hashCode$4$Method;
  private static final MethodProxy CGLIB$hashCode$4$Proxy;
  private static final Method CGLIB$clone$5$Method;
  private static final MethodProxy CGLIB$clone$5$Proxy;
  
  public RealClass$$EnhancerByCGLIB$$afcc55ac()
  {
    CGLIB$BIND_CALLBACKS(this);
  }
  
  static {}
  
  protected final void finalize()
    throws Throwable
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    if (this.CGLIB$CALLBACK_0 != null) {
      return;
    }
    super.finalize();
  }
  
  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 = tmp17_14.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy);
      tmp41_36;
      return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue();
    }
    return super.equals(paramObject);
  }
  
  public final String toString()
  {
    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) {
      return (String)tmp17_14.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy);
    }
    return super.toString();
  }
  
  public final int hashCode()
  {
    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 tmp36_31 = tmp17_14.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
      tmp36_31;
      return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue();
    }
    return super.hashCode();
  }
  
  protected final Object clone()
    throws CloneNotSupportedException
  {
    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) {
      return tmp17_14.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy);
    }
    return super.clone();
  }
  
  /* Error */
  public Object newInstance(Class[] arg1, Object[] arg2, Callback[] arg3)
  {
    // Byte code:
    //   0: aload_3
    //   1: invokestatic 206	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$SET_THREAD_CALLBACKS	([Lnet/sf/cglib/proxy/Callback;)V
    //   4: new 2	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac
    //   7: dup
    //   8: aload_1
    //   9: dup
    //   10: arraylength
    //   11: tableswitch	default:+24->35, 0:+17->28
    //   28: pop
    //   29: invokespecial 207	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:<init>	()V
    //   32: goto +17 -> 49
    //   35: goto +3 -> 38
    //   38: pop
    //   39: new 213	java/lang/IllegalArgumentException
    //   42: dup
    //   43: ldc -41
    //   45: invokespecial 218	java/lang/IllegalArgumentException:<init>	(Ljava/lang/String;)V
    //   48: athrow
    //   49: aconst_null
    //   50: invokestatic 206	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$SET_THREAD_CALLBACKS	([Lnet/sf/cglib/proxy/Callback;)V
    //   53: areturn
  }
  
  public Object newInstance(Callback[] paramArrayOfCallback)
  {
    CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
    CGLIB$SET_THREAD_CALLBACKS(null);
    return new afcc55ac();
  }
  
  public Object newInstance(Callback paramCallback)
  {
    CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
    CGLIB$SET_THREAD_CALLBACKS(null);
    return new afcc55ac();
  }
  
  public final void hah()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    if (this.CGLIB$CALLBACK_0 != null) {
      return;
    }
    super.hah();
  }
  
  public void setCallbacks(Callback[] paramArrayOfCallback)
  {
    this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramArrayOfCallback[0]);
  }
  
  public void setCallback(int paramInt, Callback paramCallback)
  {
    switch (paramInt)
    {
    case 0: 
      this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramCallback);
      break;
    }
  }
  
  public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback)
  {
    CGLIB$STATIC_CALLBACKS = paramArrayOfCallback;
  }
  
  public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback)
  {
    CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
  }
  
  public Callback getCallback(int paramInt)
  {
    CGLIB$BIND_CALLBACKS(this);
    switch (paramInt)
    {
    case 0: 
      break;
    }
    return null;
  }
  
  public Callback[] getCallbacks()
  {
    CGLIB$BIND_CALLBACKS(this);
    return new Callback[] { this.CGLIB$CALLBACK_0 };
  }
  
  final int CGLIB$hashCode$4()
  {
    return super.hashCode();
  }
  
  final void CGLIB$hah$0()
  {
    super.hah();
  }
  
  final String CGLIB$toString$3()
  {
    return super.toString();
  }
  
  final boolean CGLIB$equals$2(Object paramObject)
  {
    return super.equals(paramObject);
  }
  
  final void CGLIB$finalize$1()
    throws Throwable
  {
    super.finalize();
  }
  
  final Object CGLIB$clone$5()
    throws CloneNotSupportedException
  {
    return super.clone();
  }
  
  private static final void CGLIB$BIND_CALLBACKS(Object paramObject)
  {
    afcc55ac localafcc55ac = (afcc55ac)paramObject;
    if (!localafcc55ac.CGLIB$BOUND)
    {
      localafcc55ac.CGLIB$BOUND = true;
      Object tmp23_20 = CGLIB$THREAD_CALLBACKS.get();
      if (tmp23_20 == null)
      {
        tmp23_20;
        CGLIB$STATIC_CALLBACKS;
      }
      localafcc55ac.CGLIB$CALLBACK_0 = (tmp31_28 == null ? tmp31_28 : (MethodInterceptor)((Callback[])tmp23_20)[0]);
    }
  }
  
  static void CGLIB$STATICHOOK1()
  {
    CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    CGLIB$emptyArgs = new Object[0];
    Class localClass1 = Class.forName("Cglib第三方代理.RealClass$$EnhancerByCGLIB$$afcc55ac");
    Class localClass2;
    Method[] tmp50_47 = ReflectUtils.findMethods(new String[] { "hah", "()V" }, (localClass2 = Class.forName("Cglib第三方代理.RealClass")).getDeclaredMethods());
    CGLIB$hah$0$Method = tmp50_47[0];
    CGLIB$hah$0$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "hah", "CGLIB$hah$0");
    tmp50_47;
    Method[] tmp143_140 = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (localClass2 = Class.forName("java.lang.Object")).getDeclaredMethods());
    CGLIB$finalize$1$Method = tmp143_140[0];
    CGLIB$finalize$1$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "finalize", "CGLIB$finalize$1");
    Method[] tmp163_143 = tmp143_140;
    CGLIB$equals$2$Method = tmp163_143[1];
    CGLIB$equals$2$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
    Method[] tmp183_163 = tmp163_143;
    CGLIB$toString$3$Method = tmp183_163[2];
    CGLIB$toString$3$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
    Method[] tmp203_183 = tmp183_163;
    CGLIB$hashCode$4$Method = tmp203_183[3];
    CGLIB$hashCode$4$Proxy = MethodProxy.create(localClass2, localClass1, "()I", "hashCode", "CGLIB$hashCode$4");
    Method[] tmp223_203 = tmp203_183;
    CGLIB$clone$5$Method = tmp223_203[4];
    CGLIB$clone$5$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
    tmp223_203;
    return;
  }
  
  /* Error */
  public static MethodProxy CGLIB$findMethodProxy(net.sf.cglib.core.Signature arg0)
  {
    // Byte code:
    //   0: aload_0
    //   1: invokevirtual 128	java/lang/Object:toString	()Ljava/lang/String;
    //   4: dup
    //   5: invokevirtual 129	java/lang/Object:hashCode	()I
    //   8: lookupswitch	default:+132->140, -1574182249:+60->68, -1224815994:+72->80, -508378822:+84->92, 1826985398:+96->104, 1913648695:+108->116, 1984935277:+120->128
    //   68: ldc -125
    //   70: invokevirtual 132	java/lang/Object:equals	(Ljava/lang/Object;)Z
    //   73: ifeq +68 -> 141
    //   76: getstatic 64	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$finalize$1$Proxy	Lnet/sf/cglib/proxy/MethodProxy;
    //   79: areturn
    //   80: ldc -122
    //   82: invokevirtual 132	java/lang/Object:equals	(Ljava/lang/Object;)Z
    //   85: ifeq +56 -> 141
    //   88: getstatic 46	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$hah$0$Proxy	Lnet/sf/cglib/proxy/MethodProxy;
    //   91: areturn
    //   92: ldc -120
    //   94: invokevirtual 132	java/lang/Object:equals	(Ljava/lang/Object;)Z
    //   97: ifeq +44 -> 141
    //   100: getstatic 125	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$clone$5$Proxy	Lnet/sf/cglib/proxy/MethodProxy;
    //   103: areturn
    //   104: ldc -118
    //   106: invokevirtual 132	java/lang/Object:equals	(Ljava/lang/Object;)Z
    //   109: ifeq +32 -> 141
    //   112: getstatic 77	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$equals$2$Proxy	Lnet/sf/cglib/proxy/MethodProxy;
    //   115: areturn
    //   116: ldc -116
    //   118: invokevirtual 132	java/lang/Object:equals	(Ljava/lang/Object;)Z
    //   121: ifeq +20 -> 141
    //   124: getstatic 94	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$toString$3$Proxy	Lnet/sf/cglib/proxy/MethodProxy;
    //   127: areturn
    //   128: ldc -114
    //   130: invokevirtual 132	java/lang/Object:equals	(Ljava/lang/Object;)Z
    //   133: ifeq +8 -> 141
    //   136: getstatic 107	Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$hashCode$4$Proxy	Lnet/sf/cglib/proxy/MethodProxy;
    //   139: areturn
    //   140: pop
    //   141: aconst_null
    //   142: areturn
  }
}

JDK的代理必须是真实类有接口实现,代理类有InvocationHandler实现,代理类组合真实类有初始化真实类的构造器,
因为Proxy.newInstance需要类加载器,接口class类型,InvocationHandler实现类作为参数传入

Cglib的代理必须是真实类非final,代理类实现MethodInceptor接口,会创建真实类的子类,子类调用某一方法时,先判断

  public final void hah()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    if (this.CGLIB$CALLBACK_0 != null) {
      return;
    }
    super.hah();
  }

可参考https://www.jianshu.com/p/9a61af393e41?from=timeline&isappinstalled=0

猜你喜欢

转载自blog.csdn.net/qq_27378875/article/details/81408729