spring 如何决定使用jdk动态代理和cglib(转)
Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。(建议尽量使用JDK的动态代理)
如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。
如果你希望强制使用CGLIB代理,(例如:希望代理目标对象的所有方法,而不只是实现自接口的方法)那也可以。但是需要考虑以下问题:
无法通知(advise)Final 方法,因为他们不能被覆写。
你需要将CGLIB 2二进制发行包放在classpath下面,与之相较JDK本身就提供了动态代理
强制使用CGLIB代理需要将 |aop:config| 的 proxy-target-class 属性设为true:
|aop:config proxy-target-class="true"|
...
|/aop:config|
当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 |aop:aspectj-autoproxy| 的 proxy-target-class 属性:
|aop:aspectj-autoproxy proxy-target-class="true"/|
而实际使用的过程中才会发现细节问题的差别,The devil is in the detail.JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。
Spring是依靠什么来判断采用哪种代理策略来生成AOP代理呢?以下代码就是Spring的判断逻辑
//org.springframework.aop.framework.DefaultAopProxyFactory
//参数AdvisedSupport 是Spring AOP配置相关类
public AopProxy createAopProxy(AdvisedSupport advisedSupport)
throws AopConfigException {
//在此判断使用JDK动态代理还是CGLIB代理
if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass()
|| hasNoUserSuppliedProxyInterfaces(advisedSupport)) {
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. "
+ "Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(advisedSupport);
} else {
return new JdkDynamicAopProxy(advisedSupport);
}
}
advisedSupport.isOptimize()与advisedSupport.isProxyTargetClass()默认返回都是false,所以在默认情况下目标对象有没有实现接口决定着Spring采取的策略,当然可以设置advisedSupport.isOptimize()或者advisedSupport.isProxyTargetClass()返回为true,这样无论目标对象有没有实现接口Spring都会选择使用CGLIB代理。
所以在默认情况下,如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出java.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。
上说的是默认情况下,也可以手动配置一些选项使Spring采用CGLIB代理。
org.springframework.transaction.interceptor.TransactionProxyFactoryBean是org.springframework.aop.framework. ProxyConfig的子类,所以可以参照ProxyConfig里的一些设置如下所示,将optimize和proxyTargetClass任意一个设置为true都可以强制Spring采用CGLIB代理。
如果当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 |aop:aspectj-autoproxy| 的 proxy-target-class 属性:
|aop:aspectj-autoproxy proxy-target-class="true"/|
这样使用CGLIB代理也就不会出现前面提到的ClassCastException问题了,也可以在性能上有所提高,关键是对于代理对象是否继承接口可以统一使用。
转载于:https://www.cnblogs.com/devilwind/p/8862051.html
spring 如何决定使用jdk动态代理和cglib(转)相关推荐
- Spring AOP之---基于JDK动态代理和CGLib动态代理的AOP实现
AOP(面向切面编程)是OOP的有益补充,它只适合那些具有横切逻辑的应用场合,如性能监测,访问控制,事物管理,日志记录等.至于怎么理解横切逻辑,敲完实例代码也就明白了. 为什么要使用AOP,举个栗子: ...
- Spring AOP底层实现- JDK动态代理和CGLIB动态代理
Spring AOP是运行时织入的,那么运行时织入到底是怎么实现的呢?答案就是代理对象. 代理又可以分为静态代理和动态代理. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前, ...
- jdk动态代理和cglib动态代理的区别
一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件 ...
- 利用代码分别实现jdk动态代理和cglib动态代理_设计模式专题04-代理模式
代理模式(下一篇:建造者模式) 什么是代理模式 通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理.既(AOP微实现) ,AOP核心技术面向切面编程. 代理模式应用场 ...
- Spring AOP源码分析(二)JDK动态代理和CGLIB介绍
2019独角兽企业重金招聘Python工程师标准>>> 本篇是介绍java实现代理对象的两种方法,JDK动态代理和CGLIB. JDK动态代理:针对你所调用的方法是接口所定义的方法. ...
- Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理
Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理 代理模式 JDK动态代理 CGLIB动态代理 代理模式 代理模式是23种设计模式的一种,指一个对象A通过持有另一个对象B,可以具有B ...
- JAVA 进阶篇 动态代理 JDK动态代理和CGlib动态代理
JDK动态代理和CGlib动态代理 JDK动态代理: 利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. CGlib动态代理: 利用ASM(开源的Java ...
- Java两种动态代理JDK动态代理和CGLIB动态代理
目录 代理模式 JDK动态代理 cglib动态代理 测试 代理模式 代理模式是23种设计模式的一种,他是指一个对象A通过持有另一个对象B,可以具有B同样的行为的模式.为了对外开放协议,B往往实现了一个 ...
- Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别
视频功能审核通过了,可以看视频啦!记得点关注啊~ 注意:因为网络原因,视频前一两分钟可能会比较模糊,过一会儿就好了 记得点关注啊,视频里的wx二维码失效了,wx搜索:"聊5毛钱的java&q ...
最新文章
- python 功能 代码_挑战“不可能”的代码:你不知道的Python功能
- easyui英文提示变中文
- Hibernate 参数设置一览表
- Linux通过XAMPP集成软件包搭建LAMPP环境
- sqlldr导入时报少半个引号
- android 4.0之前版本号出现JSONException异常
- php开启curl和openssl
- 【CodeForces - 144D】Missile Silos(单源最短路,枚举中间边,枚举情况可能性)
- 零基础程序员如何快速学会python
- Gulp新手入门教程
- 仿QQ校友DIV模拟窗口
- wcf编程用什么工具_四个强大的自学编程网站工具,用的人都是学习欲望很强!...
- 漫谈Java IO之 NIO那些事儿
- CSDN搜索可以搜博客代码了
- Unix/Linux入门篇
- 线性代数高斯课堂笔记2
- 斐讯K2 烧写第三方固件的简单方法
- 计算机自带游戏如何删除,win7怎么彻底删除自带游戏,win7自带游戏怎么删除隐藏...
- sun.net.ftp.FtpClient 中文API
- Bug软件缺陷管理制度
热门文章
- 快速排序比较次数_归并排序「从入门到放弃」
- 本科计算机技术与应用知识点,《软件工程》经典考试例题题,重点的知识点(含答案)...
- android以view建坐标系,android自定义View——坐标系
- AcWing 1960. 闪烁(状态压缩+枚举)
- 汇率兑换 双向兑换_常出国的你一定要看:如何兑换外币最省钱?
- Scala中如何优雅的处理Null
- won10 mysql 5.7.22主从同步
- HashMap的小知识点
- 说下自己看源码的一点经验(Python Web 相关)
- 机房(厂房)温度环境监控系统