Spring如何选择使用CGLIB还是JDK作为Proxy
2010-04-23 15:39
344 查看
如果要使用Spring的aop特性,类就必须转换为Proxy,让Spring去管理切入点,jdk和cglib的性能差别不大,但是各有自
己的限制:
JDK dynamic proxies:
The class has
to implement interfaces. Otherwise you will get ClassCastExceptions
saying that $Proxy0 can not be casted to the particular class.
Eventually dynamic proxies force you to program to interfaces since
you can not cast the proxy to the class – a feature I really
like about
them.
CGLib proxies:
The proxies are created by sub-classing the actual class. This means
wherever an instance of the class is used it is also possible to use
the CGLib proxy.
The class needs to provide a default constructor, i.e. without any
arguments. Otherwise you’ll get an IllegalArgumentException: “Superclass
has no null constructors but no arguments were given.” This makes
constructor injection impossible.
The proxying does not work with final methods since the proxy sub
class can not override the class’ implementation.
The CGLib proxy is final, so proxying a proxy does not work. You
will get an IllegalArgumentException saying “Cannot subclass final class
$Proxy0″. But this feature is usually not needed anyway. (This issue
might be solved in
the future.)
Since two objects are created (the instance of the class and the
proxy as instance of a sub class) the constructor is called twice. In
general this should not matter. I consider changing the class’ state
based on constructor calls a code smell anyway.
You have CGLib as additional dependency.
如果你的类继承了某个父类,或者实现了某个接口,因为Spring没有办法判断这个是jdk自带的接口,还是你自己实现的接口,所以Spring就
默认使用jdk proxy了,这样子类必须要实现了一个接口,然后用这个接口来调用该类,某则就会报:
$Proxy0 cannot be cast to xxx
之类的错误,但是也可以通过强制指定使用cglib,用下面的语句:
<bean id=”userPreferences” class=”com.foo.DefaultUserPreferences”
scope=”session”>
<aop:scoped-proxy proxy-target-class=”true” />
</bean>
这样子就可以强制使用cglib,也可以直接cast该类了,当然这不是一种好习惯,实现自己的接口在测试和替换的时候毕竟比较灵活。
己的限制:
JDK dynamic proxies:
The class has
to implement interfaces. Otherwise you will get ClassCastExceptions
saying that $Proxy0 can not be casted to the particular class.
Eventually dynamic proxies force you to program to interfaces since
you can not cast the proxy to the class – a feature I really
like about
them.
CGLib proxies:
The proxies are created by sub-classing the actual class. This means
wherever an instance of the class is used it is also possible to use
the CGLib proxy.
The class needs to provide a default constructor, i.e. without any
arguments. Otherwise you’ll get an IllegalArgumentException: “Superclass
has no null constructors but no arguments were given.” This makes
constructor injection impossible.
The proxying does not work with final methods since the proxy sub
class can not override the class’ implementation.
The CGLib proxy is final, so proxying a proxy does not work. You
will get an IllegalArgumentException saying “Cannot subclass final class
$Proxy0″. But this feature is usually not needed anyway. (This issue
might be solved in
the future.)
Since two objects are created (the instance of the class and the
proxy as instance of a sub class) the constructor is called twice. In
general this should not matter. I consider changing the class’ state
based on constructor calls a code smell anyway.
You have CGLib as additional dependency.
如果你的类继承了某个父类,或者实现了某个接口,因为Spring没有办法判断这个是jdk自带的接口,还是你自己实现的接口,所以Spring就
默认使用jdk proxy了,这样子类必须要实现了一个接口,然后用这个接口来调用该类,某则就会报:
$Proxy0 cannot be cast to xxx
之类的错误,但是也可以通过强制指定使用cglib,用下面的语句:
<bean id=”userPreferences” class=”com.foo.DefaultUserPreferences”
scope=”session”>
<aop:scoped-proxy proxy-target-class=”true” />
</bean>
这样子就可以强制使用cglib,也可以直接cast该类了,当然这不是一种好习惯,实现自己的接口在测试和替换的时候毕竟比较灵活。
相关文章推荐
- Spring: proxy-target-class 决定 用 CGlib 还是 JDK AOP 来生成代理
- spring 动态代理如何决定使用jdk代理和cglib(网易面试题)
- spring 如何决定使用jdk动态代理和cglib(网易面试题)
- spring 如何决定使用jdk动态代理和cglib(网易面试题)
- 在spring来管理实例对象prototype和singleton的选择.针对action如何使用
- Sring如何选择JDK动态代理与CGLIB字节码增强
- 如何选择使用多进程还是多线程
- [转载]ASP.NET Web 服务还是 .NET Remoting:如何选择,使用 Microsoft .NET 建立分布式应用程序
- 在spring来管理实例对象prototype和singleton的选择.针对action如何使用
- 如何选择使用抽象类还是接口
- 15_传智播客Spring2.5视频教程_使用JDK中的Proxy技术实现AOP功能 2
- Spring中AOP的JDKProxy和CGlibProxy的区别
- Spring 如何将无法使用new操作符新建的对象作为spring的bean (使用FactoryBean接口)
- JDK、CGLIB、Spring三种实现代理的区别(一)JDK Proxy 解析基于Java 8
- MyEclipse下如何安装和使用ibatis插件(网上的资料对于myeclipse8.5根本就是没有用的,所以我还是自己选择了装了一个eclipse,然后将插件装在了eclipse中)
- Spring源码-AOP(二)-jdkProxy与cglib
- Spring实例化bean如何决定用JDK反射或CGLIB时机
- Spring boot中出现JDK dynamic proxy使用@Resource注入实例出现问题
- spring aop学习8:spring对jdk和cglib动态代理的选择
- ITCAST视频-Spring学习笔记(使用JDK中的Proxy技术实现AOP功能)