CGLIB和JDK代理生成新的字节码后调用的不同

JDK 代理和 CGLib代理字节码调用实现

JDK

例如我们要增强的是ISendBook接口

JDK 主要依靠反射实现调用

增强类可以看作是一个extends Proxy implements ISendBook的实现类,是Java通过sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class<?>[], int)方法自己产生了增强类的一个Class对象,

protected final class $Proxy0 extends Proxy implements ISendBook {
	// m1 代表equals方法的Method对象
	// m2 代表toString方法的Method对象
	// m3 代表sendBook方法的
	// m0 代表hashCode()
	// 在类被加载的时候就加载初始化Method对象
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
    	// 这个代理对象持有InvocationHandler的引用
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
 
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void sendBook() throws  {
        try {
           // 调用SendBookInvocationHandler 增强处理器的invoke方法
        //SendBookInvocationHandler内部的invoke 通过反射调用被增强对象的方法。
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("proxy.ISendBook").getMethod("sendBook");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

​ CGLIB

CGLIb是靠生成字节码来实现调用(例如实现的父类是Customer)

public class Customer {
    public void findLove() {
        System.out.println("大长腿");
    }
}

CGLIb会通过字节码来处理,

他会生成3个类

Customer$$EnhancerByCGLIB$$a1d847ad$$FastClassByCGLIB$$f9a35792 extends FastClass
Customer$$EnhancerByCGLIB$$a1d847ad extends Customer implements Factory
Customer$$FastClassByCGLIB$$18de439e extends FastClass

在实现方面CGLIB通过implements MethodInterceptor

产生的代理对象会extends Customer implements Factory

它实现findLove方法 并且持有增强的引用,findLove()调用增强类CglibMeipo implements MethodInterceptor 的intercept()方法,嵌入增强方法和methodProxy.invokeSuper(o, objects);

// CGLIB$findLove$0$Method 是Method对象
// CGLIB$emptyArgs
//  CGLIB$findLove$0$Proxy 是一个MethodProxy
methodInterceptor.intercept(this, CGLIB$findLove$0$Method, CGLIB$emptyArgs, CGLIB$findLove$0$Proxy);

运行的第一次会创建Fast类

这个fast类会根据方法签名返回方法的索引值

Customer$$EnhancerByCGLIB$$a1d847ad$$FastClassByCGLIB$$f9a35792

Fast类

FastClassInfo fci = fastClassInfo;
// fci.i2 :
// obj : Customer$$EnhancerByCGLIB$$a1d847ad
// 通过顺序id switch case 找到对应的入口执行obj的CGLIB$findLove$0();这个方法会调用父类的方法
return fci.f2.invoke(fci.i2, obj, args);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值