jdk和cglib代理

静态代理

继承

代理对象继承目标对象,重写需要增强的方法;

缺点:类膨胀

聚合

目标对象和代理对象实现同一个接口,代理对象属性为目标对象。

缺点:也会类膨胀,只不过比继承少

动态代理

简单思路

不手动创建类文件,通过接口反射生成一个类文件,然后调用第三方的编译技术,动态编译这个产生的类文件成class文件,继而利用UrlclassLoader(因为这个动态产生的class不在工程当中所以需要使用UrlclassLoader)把这个动态编译的类加载到jvm当中,最后通过反射把这个类实例化。

缺点:性能不高,还需优化

jdk动态代理

判断一个类是否相同,要看他的类加载是不是相同

动态加载一个类,需要三个参数,目的是在同一个类加载器下通过接口创建出一个动态的类

ClassLoader loader
Class<?>[] interfaces
InvocationHandler h(我们想的可能直接传方法Methed ,其实传入目标对象更好,而jdk进行了封装与优化)

jdk动态代理流程差不多如下(有人喜欢把目标对象叫proxy,代理对象叫proxyObj,也有人喜欢把目标对象叫target,代理对象叫proxy)

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("jiaqiang");

                return method.invoke(xxxx,args);  //注意xxx不是参数proxy,我认为这个proxy其实是proxyObj,填入这个会无限循环
            }

jdk优点(如有错误欢迎指出):jdk使用本地方法加载的class,更快,传入的参数更加合理

从源码看了jdk只能代理接口,而不能代理类是因为已经继承了Proxy

转载了篇写的还不错的https://blog.csdn.net/a_higher/article/details/104720580

cglib动态代理

这个清晰详细:https://www.cnblogs.com/wyq1995/p/10945034.html

源代码分析:https://blog.csdn.net/yhl_jxy/article/details/80633194

怎么用:https://www.runoob.com/w3cnote/cglibcode-generation-library-intro.html

fastclass机制:是给每个方法编号,通过编号找方法

原理:

第一步:cglib生成代理对象

第二步:进入到方法拦截器的intercept()方法,在这个方法中会调用proxy.invokeSuper(obj, args)方法

第三步:invokeSuper中,通过FastClass机制调用目标类的方法

//实现了MethodInterceptor
//第一个参数代理对象,第二个参数拦截的方法,第三个参数方法中传入的参数,第四个参数是代理方法的MethodProxy对象
public Object intercept(Object obj, Method method, Object[] params,
            MethodProxy proxy) throws Throwable {
        System.out.println("调用前");
        Object result = proxy.invokeSuper(obj, params);
        System.out.println(" 调用后"+result);
        return result;
    }

由于CGLIB的大部分类是直接对Java字节码进行操作,这样生成的类会在Java的永久堆中。如果动态代理操作过多,容易造成永久堆满,触发OutOfMemory异常

Enhancer不能够拦截final方法和final类

不同:

Java动态代理使用Java原生的反射API进行操作,在生成类上比较高效;CGLIB使用ASM框架直接对字节码进行操作,在类的执行过程中比较高效

JDK的动态代理是通过接口来进行强制转换的生成以后的代理对象,可以强制转换为接口

CGLib的动态代理是通过生成一个被代理对象的子类,然后重写父类的方法 ,生成以后的对象,可以强制转换为被代理对象(也就是用自己写的类),即子类引用赋值给父类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值