您的位置:首页 > 编程语言 > Java开发

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该类了,当然这不是一种好习惯,实现自己的接口在测试和替换的时候毕竟比较灵活。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐