JDK和CGLIB生成动态代理类的区别
关于动态代理和静态代理
当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象。
按照代理对象的创建时期不同,可以分为两种:
静态代理:事先写好代理对象类,在程序发布前就已经存在了;
动态代理:应用程序发布后,通过动态创建代理对象。
静态代理其实就是一个典型的代理模式实现,在代理类中包装一个被代理对象,然后影响被代理对象的行为,比较简单,代码就不放了。
其中动态代理又可分为:JDK动态代理和CGLIB代理。
1.JDK动态代理
此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。
代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。
JDK动态代理只能针对实现了接口的类生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,
主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。
JDK动态代理和CGLIB代理生成的区别
JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。
因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。
PS:final 所修饰的数据具有“终态”的特征,表示“最终的”意思:
- final 修饰的类不能被继承。
- final 修饰的方法不能被子类重写。
- final 修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。
- final 修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有 一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
- final 修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。
参考代码
CGLIB:
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;// 返回代理对象,返回的对象其实就是一个封装了“实现类”的代理类,是实现类的实例。
}
JDK:
public Object newProxy(Object targetObject) {// 将目标对象传入进行代理
this.targetObject = targetObject;
//注意这个方法的参数,后面是类实现的接口
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);// 返回代理对象
}
在代码中可以看到,在生成代理类时,传递的是实现类所实现的接口 targetObject.getClass().getInterfaces(),所以JDK只能对于接口进行做代理。如果换成类的话,则会抛java.lang.ClassCastException异常。
在Spring的源码中,可以看到很多生成代理类的代码。
动态代理的应用
AOP(Aspect-OrientedProgramming,面向切面编程),AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。
实现AOP的技术,主要分为两大类:
一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。
默认的策略是如果目标类是接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。
如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。
JDK和CGLIB生成动态代理类的区别的更多相关文章
- 【4】JDK和CGLIB生成动态代理类的区别
当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代理:事先写好代理对象类,在 ...
- JDK和CGLIB生成动态代理类的区别(转)
关于动态代理和静态代理 当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代 ...
- CGLIB 和 JDK生成动态代理类的区别(转)
文章转自http://luyuanliang.iteye.com/blog/1137292 AOP 使用的设计模式就是代理模式,是对IOC设计的补充.为了扩展性,往往会加上反射,动态生成字节码,生成代 ...
- JDK 和 CGLib 实现动态代理和区别
JDK 和 CGLib 实现动态代理和区别 在日常的开发中,Spring AOP 是一个非常常用的功能.谈到 AOP,自然离不开动态代理. 那么,基于 JDK 和 CGLib 如何实现动态代理,他们之 ...
- JDK和Cglib实现动态代理实例及优缺点分析
Spring AOP使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率.打印 ...
- jdk与cglib的动态代理
JDK动态代理中包含一个类和一个接口: InvocationHandler接口: public interface InvocationHandler { public Object invoke(O ...
- cgLib生成动态代理
package com.stono.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import ...
- java面试题之spring aop中jdk和cglib哪个动态代理的性能更好?
在jdk6和jdk7的时候,jdk比cglib要慢: 在jdk8的时候,jdk性能得到提升比cglib要快很多: 结论出自:https://www.cnblogs.com/xuliugen/p/104 ...
- Alibaba Java诊断工具Arthas查看Dubbo动态代理类
原创/朱季谦 阅读Dubbo源码过程中,会发现,Dubbo消费端在做远程调用时,默认通过 Javassist 框架为服务接口生成动态代理类,接着再去调用代理类实现远程接口调用.在阅读这部分源码时,最后 ...
随机推荐
- bzoj千题计划299:bzoj1856: [Scoi2010]字符串
http://www.lydsy.com/JudgeOnline/problem.php?id=1856 卡特兰数 从(1,1)走到(n,m),不能走y=x 上方的点,求方案数 从(1,1)走到(n, ...
- vue常用UI组件
Mint UI 项目主页:http://mint-ui.github.io/#!/zh-cn demo:http://elemefe.github.io/mint-ui/#/ github地址:htt ...
- JAVA Socket 编程---Socket 和 ServerSocket
一,Socket Socket的选项 1) TCP_NODELAY:默认值为false.表示采用Negale算法.当设置为true时,表示关闭Socket缓冲,立即发送数据. Socket默认发送数据 ...
- js 运动框架及实例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 字体选择框QFontComboBox
self.combobox_2 = QFontComboBox(self) # 实例化字体列表框 combobox.currentFont() 返回字体选择框中当前的字体 self.combobo ...
- [Offer收割]编程练习赛9,10
题目1 : 闰秒 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 计算机系统中使用的UTC时间基于原子钟,这种计时方式同“地球自转一周是24小时”的计时方式有微小的偏差. ...
- 第18月第16天 statusBar
1. 我们都知道要改状态栏statusBar的颜色很简单,只要如下一行代码就可以, [[UIApplicationsharedApplication]setStatusBarStyle:UIStatu ...
- dp之免费馅饼
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- AJAX请求头Content-type
发送json格式数据 xhr.setRequestHeader("Content-type","application/json; charset=utf-8" ...
- np.savetxt()——将array保存到txt文件,并保持原格式
问题:1.如何将array保存到txt文件中?2.如何将存到txt文件中的数据读出为ndarray类型? 需求:科学计算中,往往需要将运算结果(array类型)保存到本地,以便进行后续的数据分析. 解 ...