May 14 2009


Category: 技术ssmax @ 10:11:37


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


<bean id=”userPreferences” class=”” scope=”session”>
    <aop:scoped-proxy proxy-target-class=”true” />