两种动态代理:JDK实现和CGLIB字节码生成文件

静态代理:由程序员创建或工具生成代理类的源码,再编译代理类,即代理类和委托类的关系再程序运行前就已经存在。
动态代理:在运行期间使用动态生成字节码形式,动态创建代理类。使用的工具有 jdkproxy、cglibproxy 等。

JDK实现动态代理:

利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

  1. JDK动态代理只能代理有接口的类,并且是能代理接口方法,不能代理一般的类中的方法
  2. 提供了一个使用InvocationHandler作为参数的构造方法。在代理类中做一层包装,业务逻辑在invoke方法中实现
  3. 重写了Object类的equals、hashCode、toString,它们都只是简单的调用了InvocationHandler的invoke方法,即可以对其进行特殊的操作,也就是说JDK的动态代理还可以代理上述三个方法
  4. 在invoke方法中我们甚至可以不用Method.invoke方法调用实现类就返回。这种方式常常用在RPC框架中,在invoke方法中发起通信调用远端的接口等

cglib动态代理

利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

两者区别

动态代理分为两种:

  • jdk的动态代理
    • 代理对象和目标对象实现了共同的接口
    • 拦截器必须实现InvocationHanlder接口,其中的invoke方法是执行代理时会执行的方法(参数是要代理的方法),并且同时传入自身被调用的方法的的Method对象和参数列表方便我们编码实现方法的调用。
  *  cglib的动态代理(要用到cglib的jar包)
     *  代理对象是目标对象的子类
     *  拦截器必须实现MethodInterceptor接口
     *  hibernate中session.load采用的是cglib实现的

JDK动态代理和CGLIB字节码生成的区别?
1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类。

2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,
并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,
对于final类或方法,是无法继承的。

Spring如何选择用JDK还是CGLiB?

1)当Bean实现接口时,Spring就会用JDK的动态代理。

2)当Bean没有实现接口时,Spring使用CGlib是实现。

3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>)。

JDK和CGLIB动态代理总结

JDK代理是不需要第三方库支持,只需要JDK环境就可以进行代理,使用条件:

1)实现InvocationHandler

2)使用Proxy.newProxyInstance产生代理对象

3)被代理的对象必须要实现接口

CGLib必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,
覆盖其中的方法,是一种继承但是针对接口编程的环境下推荐使用JDK的代理;

部分转自:https://blog.youkuaiyun.com/yhl_jxy/article/details/80635012

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值