`
flyfoxs
  • 浏览: 297740 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

Cglib为什么不能完全替换 动态代理

 
阅读更多

看到好多地方对比CGLIB和动态代理来实现AOP的, 感觉就是一边倒的. CGLIB什么都好, 比如:

  •  目标对象可以是Interface或者Class,不像动态代理只支持Interface
  •  CGlib性能也好.

 

看到这些,我就有一个疑问, 既然如此优秀, 为什么动态代理还有存在的必要呢.带着这个疑问,我研究了一下CGLIB的不足.对比动态代理来实现AOP,CGLIB需要有2个前提条件,都是动态代理不存在的.

  • final Class不支持, 因为CGLIB是生成子类来实现AOP,所以final Class自然无法支持了.
  • 需要强制无参数构造函数 

其实从JAVA实现AOP这个角度,大致有2个方法,

  • 一个是通过设计模式:比如代理,装饰器,责任链之类. 这几种的前提就是前期设计比较好,也就是要设计要依赖于接口而不是实现. 比如我认为Struts2的拦截器也是AOP的一种.
  • 一个就是生成子类:也就是Cglib所选择的这种方法,就会有上面所说说的2个限制.

 

2
3
分享到:
评论
11 楼 ziguopu 2014-05-31  
ray_yui 写道
ray_yui 写道
flyfoxs 写道
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数



你说的蛮对的.

问一个问题.是不是就是CGLIB完全,彻底的把动态代理比下去了. 动态代理能做的Cglib都可以做到,并且做得更好?

其实不该争论谁把谁比下去这个问题.从不同角度有不同的看法,例如我的业务只用到JDK的动态代理就能实现,那你是用CGLIB可以说是增加了代码阅读的难度,毕竟JDK的动态代理更多人熟悉,在这样的背景下使用CGLIB是不好的,那如果你的业务JDK的动态代理满足不到,而CGLIB能满足,那CGLIB就比JDK动态代理好一亿,十亿倍,因为它能帮助你完成你需要的.若然你两个都不喜欢,完全自己写一套自己的动态代理也是没问题的.不要为小问题纠结.谁能完成你的需要,就是最好的.需要包括 扩展,性能,代码可阅读性,另外,CGLIB确实能涵盖JDK动态代理的所有功能而且做得更好.

举个例子,当你项目中一个类已经被设计成一个类,但某一天他需要被动态代理,这样的场景下能使用JDK动态代理吗?那只能是CGLIB,这时CGLIB对开发来说就是春天.庆幸有这样的一个现成的工具支持,当你需要对接口动态代理,又对性能没要求时,杀鸡就不用牛刀,直接使用JDK动态代理还可以增强代码可读性,这时CGLIB就成了可有可无.CGLIB是你的春天还是你没用的东西,全在你业务需要



那cglib有什么缺点?
10 楼 ray_yui 2014-05-31  
ray_yui 写道
flyfoxs 写道
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数



你说的蛮对的.

问一个问题.是不是就是CGLIB完全,彻底的把动态代理比下去了. 动态代理能做的Cglib都可以做到,并且做得更好?

其实不该争论谁把谁比下去这个问题.从不同角度有不同的看法,例如我的业务只用到JDK的动态代理就能实现,那你是用CGLIB可以说是增加了代码阅读的难度,毕竟JDK的动态代理更多人熟悉,在这样的背景下使用CGLIB是不好的,那如果你的业务JDK的动态代理满足不到,而CGLIB能满足,那CGLIB就比JDK动态代理好一亿,十亿倍,因为它能帮助你完成你需要的.若然你两个都不喜欢,完全自己写一套自己的动态代理也是没问题的.不要为小问题纠结.谁能完成你的需要,就是最好的.需要包括 扩展,性能,代码可阅读性,另外,CGLIB确实能涵盖JDK动态代理的所有功能而且做得更好.

举个例子,当你项目中一个类已经被设计成一个类,但某一天他需要被动态代理,这样的场景下能使用JDK动态代理吗?那只能是CGLIB,这时CGLIB对开发来说就是春天.庆幸有这样的一个现成的工具支持,当你需要对接口动态代理,又对性能没要求时,杀鸡就不用牛刀,直接使用JDK动态代理还可以增强代码可读性,这时CGLIB就成了可有可无.CGLIB是你的春天还是你没用的东西,全在你业务需要

9 楼 ray_yui 2014-05-31  
flyfoxs 写道
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数



你说的蛮对的.

问一个问题.是不是就是CGLIB完全,彻底的把动态代理比下去了. 动态代理能做的Cglib都可以做到,并且做得更好?

其实不该争论谁把谁比下去这个问题.从不同角度有不同的看法,例如我的业务只用到JDK的动态代理就能实现,那你是用CGLIB可以说是增加了代码阅读的难度,毕竟JDK的动态代理更多人熟悉,在这样的背景下使用CGLIB是不好的,那如果你的业务JDK的动态代理满足不到,而CGLIB能满足,那CGLIB就比JDK动态代理好一亿,十亿倍,因为它能帮助你完成你需要的.若然你两个都不喜欢,完全自己写一套自己的动态代理也是没问题的.不要为小问题纠结.谁能完成你的需要,就是最好的.需要包括 扩展,性能,代码可阅读性,另外,CGLIB确实能涵盖JDK动态代理的所有功能而且做得更好.
8 楼 flyfoxs 2014-05-30  
jahu 写道
说白了,,就是动态代理实现aop比CGLIB简单,易操作。


比较的时候,没看出来简单在哪,稍后我再比较看看.谢谢评论
7 楼 jahu 2014-05-30  
说白了,,就是动态代理实现aop比CGLIB简单,易操作。
6 楼 flyfoxs 2014-05-30  
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数



你说的蛮对的.

问一个问题.是不是就是CGLIB完全,彻底的把动态代理比下去了. 动态代理能做的Cglib都可以做到,并且做得更好?
5 楼 ray_yui 2014-05-30  
ray_yui 写道
jimode2013 写道
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数
  说得很有道理,cglib的学习成本比较高,而且一般来说项目根本没有那么高的性能要求 ,除非在实际的项目中发现动态代理成为瓶颈的时候,这个时候才会使用cglib
动态代理的好处是学习成本底,而且不用引入一个新的jar包

个人认为CGLIB完全是0学习成本,google一搜一堆资料,而且在使用spring,hibernate等开源框架时cglib早早就被引入项目,也不存在引入一个新jar的问题,我认为性能那方面是可以忽略不计的,我也没用过代理class的例子,不过咸鱼白菜各有所爱,喜欢的话用两边不用用Javassist也可以

而且CGLIB有CallbackFilter,这些特别是JDK的动态代理不支持的,有兴趣click入我文章看看
4 楼 ray_yui 2014-05-30  
jimode2013 写道
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数
  说得很有道理,cglib的学习成本比较高,而且一般来说项目根本没有那么高的性能要求 ,除非在实际的项目中发现动态代理成为瓶颈的时候,这个时候才会使用cglib
动态代理的好处是学习成本底,而且不用引入一个新的jar包

个人认为CGLIB完全是0学习成本,google一搜一堆资料,而且在使用spring,hibernate等开源框架时cglib早早就被引入项目,也不存在引入一个新jar的问题,我认为性能那方面是可以忽略不计的,我也没用过代理class的例子,不过咸鱼白菜各有所爱,喜欢的话用两边不用用Javassist也可以
3 楼 jimode2013 2014-05-30  
ray_yui 写道
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数
  说得很有道理,cglib的学习成本比较高,而且一般来说项目根本没有那么高的性能要求 ,除非在实际的项目中发现动态代理成为瓶颈的时候,这个时候才会使用cglib
动态代理的好处是学习成本底,而且不用引入一个新的jar包
2 楼 kidding87 2014-05-30  
cglib 在代理class而不是Interface的时候使用的是继承,这样会导致super的构造方法被调用
1 楼 ray_yui 2014-05-30  
偶然click入楼主文章,想给楼主科普一下..动态代理完全不支持类,更别说final class,所以能支持class已经很不错了..第二CGLIB不需要无参构造函数.可以指定调用哪個構造函数

相关推荐

    java设计模式【之】Cglib动态代理【源码】【场景:帮爸爸买菜】

    java设计模式【之】Cglib动态代理【源码】【场景:帮爸爸买菜】 /** * 代理模式 * 在开发者的角度来看,创建一个代理对象,提供给用户使用,避免用户直接访问真正的对象 * 在用户角度来看,就是普通的类方法调用...

    JAVA类加载机制与动态代理

    动态代理允许我们为一个接口创建一个代理类,代理类可以是任何接口的实现。当我们调用代理类的方法时,它会调用预先定义好的拦截器,从而实现对目标对象方法的增强处理。 动态代理的主要作用是: - **增强功能**:...

    MyBatis面试题1

    MyBatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,MyBatis 通过动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口...

    Java开发工具包(数据校验,数据脱敏,类处理,Http等.....)

    数据脱敏是在保持数据真实性的前提下,对敏感信息进行部分或全部替换,以保护个人隐私和商业秘密。在Java中,可以使用正则表达式、字符串操作函数或自定义加密算法来实现。例如,对于电话号码,可以只保留前三位和...

    设计模式全部文件打包

    在Java中,静态代理和动态代理(JDK Proxy或CGLIB)是常见的实现手段。 7. **观察者模式**:定义对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。Java的java....

    Java 设计模式与建模专题

    Java中静态代理和动态代理(JDK动态代理和CGLIB动态代理)是常见实现方式。 6. **适配器模式**:将一个类的接口转换成客户希望的另一个接口。适配器让原本不兼容的类可以一起工作。 7. **策略模式**:定义一系列...

    MyBatis常见实用面试题整理.docx

    #### 7、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里? - **半自动特性**:Mybatis需要手动编写SQL语句,对于关联对象或关联集合对象的查询需要手动编写SQL。 - **全自动工具**:如Hibernate,...

    MyBatis 36道面试题和答案.docx

    与全自动的Hibernate相比,MyBatis不负责完全自动化的对象关系映射。在Hibernate中,查询关联对象可以直接获取,而MyBatis需要开发者手动编写SQL来完成关联查询。因此,MyBatis被称为半自动ORM工具,它在灵活性和...

    MyBatis面试专题.pdf

    MyBatis的延迟加载通常通过CGLIB创建目标对象的代理对象,当访问延迟加载的属性时,实际的SQL查询才会执行。 在与Hibernate的比较中,MyBatis由于需要开发者手动编写SQL语句,因此提供更多的灵活性和控制性。...

    mybatis老师总结

    - **动态代理**:利用 JDK 动态代理或者 CGLIB 生成代理对象,代理对象实现了 Mapper 接口中定义的方法。当调用代理方法时,实际上会执行 SQL 语句并与数据库交互。 #### 七、MyBatis 配置细节 - **Properties**:...

    spring框架勇于开发的核心架包

    有两种代理方式:JDK动态代理和CGLIB代理。前者适用于实现了接口的类,后者用于没有接口或接口不完全覆盖所需方法的类。 最后,Spring的核心架包还包含一系列的工具类,如类型转换系统、事件传播、资源处理等,这些...

    23种设计模式的实现(Java 版).rar

    在Java中,静态代理和动态代理(JDK和CGLIB)都是常见的实现方式。 9. **桥接模式**:将抽象部分与它的实现部分分离,使它们都可以独立地变化。 10. **组合模式**:将对象组合成树形结构以表示部分-整体的层次结构...

    MyBatis面试题(2022最新版)

    - 实现上,利用代理模式(如CGLIB)创建代理对象,在访问关联对象时触发加载。 #### 13. 映射器 - **#{}与${}的区别**: - #{}支持预编译,防止SQL注入。 - ${}直接替换变量值,可能导致SQL注入。 - **模糊查询...

    java面试题及答案-非常全面(包括基础、网络、数据结构、算法及IT大厂面经)

    - **类型**:包括JDK动态代理(实现接口)和CGLIB动态代理(子类继承)。 ### 设计模式 - **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。 - **工厂模式**:提供创建一系列相关或相互依赖对象的...

Global site tag (gtag.js) - Google Analytics