JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

区别:JDK代理只能对实现接口的类生成代理;CGlib是针对实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类

强制使用CGlib

<!-- proxy-target-class="false"默认使用JDK动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/><aop-config proxy-target-class="true">

具体代码示例

/*** 目标接口类*/
public interface UserManager {    public void addUser(String id, String password);    public void delUser(String id);
}
/*** 接口实现类*/
public class UserManagerImpl implements UserManager {    @Overridepublic void addUser(String id, String password) {    System.out.println("调用了UserManagerImpl.addUser()方法!");}    @Overridepublic void delUser(String id) {    System.out.println("调用了UserManagerImpl.delUser()方法!");}
}
/*** JDK动态代理类*/
public class JDKProxy implements InvocationHandler {    // 需要代理的目标对象private Object targetObject;    public Object newProxy(Object targetObject) {// 将目标对象传入进行代理    this.targetObject = targetObject;// 返回代理对象 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);}    // invoke方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 进行逻辑处理的函数checkPopedom();Object ret = null;// 调用invoke方法ret = method.invoke(targetObject, args);return ret;}    private void checkPopedom() {// 模拟检查权限   System.out.println("检查权限:checkPopedom()!");    }
}
/*** CGlib动态代理类*/public class CGLibProxy implements MethodInterceptor {    // CGlib需要代理的目标对象private Object targetObject;public Object createProxyObject(Object obj) {this.targetObject = obj;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(obj.getClass());enhancer.setCallback(this);Object proxyObj = enhancer.create();return proxyObj;}@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object obj = null;// 过滤方法if ("addUser".equals(method.getName())) {// 检查权限checkPopedom();}obj = method.invoke(targetObject, args);return obj;}    private void checkPopedom() {System.out.println("检查权限:checkPopedom()!");}
}
/*** 测试类*/
public class ProxyTest {public static void main(String[] args) {UserManager userManager = (UserManager)new CGLibProxy().createProxyObject(new UserManagerImpl());System.out.println("CGLibProxy:");userManager.addUser("tom", "root");System.out.println("JDKProxy:");JDKProxy jdkProxy = new JDKProxy();UserManager userManagerJDK = (UserManager)jdkProxy.newProxy(new UserManagerImpl());userManagerJDK.addUser("tom", "root");}
}
// 运行结果
CGLibProxy:
检查权限checkPopedom()!
调用了UserManagerImpl.addUser()方法!
JDKProxy:
检查权限checkPopedom()!
掉用了UserManagerImpl.addUser()方法!

总结

  1. JDK代理使用的是反射机制实现aop的动态代理,CGLIB代理使用字节码处理框架asm,通过修改字节码生成子类。所以jdk动态代理的方式创建代理对象效率较执行效率较低,cglib创建效率较低,执行效率高;
  2. JDK动态代理机制是委托机制,具体说动态实现接口类,在动态生成的实现类里面委托hanlder去调用原始实现类方法,CGLIB则使用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。

动态代理的两种方式以及区别相关推荐

  1. spring中AOP动态代理的两种方式

    AOP动态代理的两种方式 Spring AOP动态代理的方式(spring的AOP默认是JDK Proxy) 浅谈这两种动态代理 JDK的动态代理,需要有实现接口 动态代理--JDK Proxy ⚫ ...

  2. Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别

    视频功能审核通过了,可以看视频啦!记得点关注啊~ 注意:因为网络原因,视频前一两分钟可能会比较模糊,过一会儿就好了 记得点关注啊,视频里的wx二维码失效了,wx搜索:"聊5毛钱的java&q ...

  3. 动态代理的两种方式_动态代理是基于什么原理?

    代理模式 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问. 什么是动态代理 运行时动态生成代理类. 动态代理我们需要些什么 1.业务接口(Interface) 业务的抽象表示. 2.业务 ...

  4. Java实现动态代理的两种方式

    http://m.blog.csdn.net/article/details?id=49738887

  5. SpringAop动态代理的两种实现方式

    Spring的面向切面编程也是基于动态代理来实现的 静态代理:也就是自己手动创建的代理对象 动态代理:也就是在程序运行中通过配置参生的 那么Spring的AOP也就是面向切面编程,就是基于动态代理来实 ...

  6. Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理

    Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理 代理模式 JDK动态代理 CGLIB动态代理 代理模式 代理模式是23种设计模式的一种,指一个对象A通过持有另一个对象B,可以具有B ...

  7. vue 路由传参 params 与 query两种方式的区别(转载)

    vue 路由传参 params 与 query两种方式的区别 初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了:  ro ...

  8. Java动态代理的两种实现方法

    转载自 http://blog.csdn.net/HEYUTAO007/article/details/49738887 AOP的拦截功能是由java中的动态代理来实现的.说白了,就是在目标类的基础上 ...

  9. java两种绑定方式_Javascript绑定事件的两种方式的区别

    命名函数 function check(){ //code } 匿名函数 window.onload = function(){ //先获取元素对象,再绑定事件,绑定的是匿名函数不可重用 var bt ...

  10. vue 路由传参 params 与 query两种方式的区别

    vue 路由传参 params 与 query两种方式的区别 初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了:  ro ...

最新文章

  1. CMOS图像传感器理解
  2. python中字符串(比如文件路径)前面有一个r什么意思
  3. 深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor...
  4. 请解释和、|和||的区别?
  5. IPC\DVS\DVR与NVR之间的区别
  6. I/O复用函数的使用——select
  7. 大厂产品是如何做行业调研和规划的?附汇报模版(PPT)
  8. 深度剖析WinPcap之(二)——网络分析与嗅探的基础知识(4)
  9. 【干货】31篇关于深度学习必读论文汇总(附论文下载地址)
  10. 游戏开发之动态创建对象及构造函数、析构函数的执行(C++基础)
  11. java 圣思园视频资源
  12. python的invalid syntax是什么意思_请问在python 中 出现 invalid syntax 是什么意思 ?
  13. 计算机用户删除 cmd,命令提示符下怎么新建用户和删除用户
  14. sql server的元素类型int identity(1,1)是什么意思?
  15. zabbix 主动监控与被动监控
  16. Java Online IDE
  17. 如何用python完成评分功能呢_Python:豆瓣电影评分
  18. HCIP之OSPF(五)
  19. 好未来赚数倍,大跌前又精准提前离场:高瓴张磊的核心投资方法论到底是什么?
  20. 剔除半角字符和空格 java_去掉字符串中的全角,半角空格,回车,制表符

热门文章

  1. 以《西游记》为例 详解游戏设计归纳演绎法
  2. ROS导航仿真操作(3)
  3. efi分区能不能删除 win10_Win10不小心把EFI分区删除怎么恢复?
  4. 计算机老掉线 路由器网络,路由器无线掉线怎么办?
  5. css设置背景图片透明度
  6. 电脑计算机快捷键切换桌面,电脑切换界面的快捷键是什么_电脑切换桌面快捷键怎么用-win7之家...
  7. pmp中项目经理如何进行目标设定
  8. 不瞒你说,我也参加过培训
  9. bash+vasp+vaspkit能量应变计算弹性常数
  10. Modbus协议解析