Spring强制使用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问题了,也可以在性能上有所提高,关键是对于代理对象是否继承接口可以统一使用。
Spring强制使用CGLIB代理事务的更多相关文章
- spring 强制采用cglib进行代理
spring对AOP的支持 *如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP* 如果目标对象实现了接口,可以强制使用CGLIB实现AOP*如果目标对象没有实现了接口,必须采用CGL ...
- spring的AOP动态代理--JDK代理和CGLIB代理区分以及注意事项
大家都知道AOP使用了代理模式,本文主要介绍两个代理模式怎么设置以及区别,对原文一些内容进行了引用后加入了自己的理解和更深入的阐述: 一.JDK代理和CGLIB代理的底层实现区别* JDK代理只能 ...
- 浅谈Spring中JDK动态代理与CGLIB动态代理
前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...
- spring---aop(4)---Spring AOP的CGLIB动态代理
写在前面 前面介绍了Spring AOP的JDK动态代理的过程,这一篇文章就要介绍下Spring AOP的Cglib代理过程. CGLib全称为Code Generation Library,是一个强 ...
- Spring的AOP与代理
spring 支持两种注入方式: setter/constructor 支持多种配置方式: xml/java5注解/java类配置 支持两种事务管理: 声明性/编程性 实际上上述方式只有一个就能保证系 ...
- spring实现一个简单的事务管理
前两天给公司的数据库操作加了事务管理,今天博客就更一下这个吧. 先说明:本文只是简单得实现一下事务,事务的具体内容,比如事务的等级,事务的具体实现原理等等... 菜鸟水平有限,暂时还更不了这个,以后的 ...
- (转)Java动态代理与CGLib代理
<br>public class UserDAOImpl{ <br><br> public void save() { <br> / ...
- IT忍者神龟之Java动态代理与CGLib代理
<br>public class UserDAOImpl{ <br><br> public void save() { <br> / ...
- 循序渐进之Spring AOP(3) - 配置代理
上一篇介绍了几种Advice(增强),并通过代码演示了生成代理的方式,下面来看通过配置文件配置方式把Advice织入目标类. 注意,配置文件方式仍然不是spring AOP的最好方式,学习配置方式也是 ...
随机推荐
- SpringMVC——hello SpringMVC
概述: Spring的web框架围绕DispatcherServlet设计. DispatcherServlet的作用是将请求分发到不同的处理器. 与其它web MVC框架一样,Spring的web ...
- TCP/IP详解学习笔记(1)-基本概念
为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...
- Jedis的Sharded源代码分析
概述 Jedis是Redis官方推荐的Java客户端,更多Redis的客户端可以参考Redis官网客户端列表.当业务的数据量非常庞大时,需要考虑将数据存储到多个缓存节点上,如何定位数据应该存储的节点, ...
- 大话细说ORM
什么是ORM? ORM,即对象关系映射(Object Relational Mapping)表示一种技术,用来把(对象模型)表示的对象映射到基于SQL的(关系模型)数据结构中去. 说得通俗点,就是在对 ...
- 机器学习真的可以起作用吗?(2)(以二维PLA算法为例)
一个问题:大多数情况下,M(hypothesis set的大小)是无穷大的,例如PLA算法.那么是不是我们的原则1就不能使用了? 我们试着做一些努力: Step1:寻找hypothesis set的e ...
- Tkinter教程之Canvas篇(2)
本文转载自:http://blog.csdn.net/jcodeer/article/details/1811888 '''Tkinter教程之Canvas篇(2)''''''9.创建item的tag ...
- linux vim用法总结
1.跳转到指定行 编辑模式下:输入 ngg或nG(n代表行数) 命令模式下:输入 :n(n代表行数) 2.查找命令 命令模式下输入 / 后面加上查找的内容 例如 :/name (查找 ...
- flot图表的使用
Flot是一套用Javascript写的绘制图表用的函式库, 专门用在网页上执行绘制图表功能, 由于Flot利用jQuery所以写出来的, 所以也称它为jQuery Flot ,它的特点是体积小.执行 ...
- voip的会议服务器Conference Servers
http://openmcu.ru/eng.htm openmcu: http://h323plus.cvs.sourceforge.net/viewvc/h323plus/application ...
- 【转】Maven实战(二)---多模块开发---缺少Jar包
原博文出于:http://blog.csdn.net/liutengteng130/article/details/41611755 感谢! Maven里面的Jar包经常出现Missing的情况 ...