of type 'shiyaxin.service.impl.AccountServiceImpl' but was actually oftype 'com.sun.proxy.$Prox从根解决错

痛定思痛。 2024-04-19 10:35 118阅读 0赞
  1. <!-- 配置aop建立日志类在指定方法(切面)执行之前执行-->
  2. <aop:config >
  3. <!-- 配置切面-->
  4. <aop:aspect id="logAdvice" ref="logger">
  5. <!-- 配置通知的类型,并且建立通知方法和切入点方法的关联-->
  6. <aop:before method="printLog" pointcut="execution(public void com.shiyaxin.service.impl.AccountServiceImpl.saveAccount())"></aop:before>
  7. </aop:aspect>
  8. </aop:config>
  9. 我的解决办法是:学习Spring框架的时候,很容易犯下的一个错误,需要在配置文件中打开aop命名空间,并设置如下属性:
  10. <aop:config proxy-target-class="true">

该属性值默认为false,表示使用JDK动态代理织入增强;当值为true时,表示使用CGLib动态代理织入增强;但是,即使设置为false,如果目标类没有生命接口,

则Spring将自动使用CGLib动态代理.(以上来自:Spring3.X企业应用开发实战 P229)

通俗理解:

当要使用实现了某个接口的类让Spring来生成bean时,无需在aop配置中添加proxy-target-class,因为它默认为false.

但如果要使用一个指定的类,让Spring来生成bean,并使用它的某个方法时,需要在aop配置上加上一句proxy-target-class=“true”,否则用JUnit时,会出现:

java.lang.ClassCastException: com.sun.proxy.$Proxy6 cannot be cast to glut.daoImp2.DAOImp2
///
查了一下spring的配置文件applicationContext.xml,发现里面少了一句aop:aspectj-autoproxy/配置。但是加上之后仍然报错。这是为什么呢。

再查看这个标签有一个属性:proxy-target-class,它的值有false(默认)和true。再将它设置成true之后,结果运行成功了。总结一下原因如下:

  1. <aop:aspectj-autoproxy proxy-target-class="false"/> 基于接口,使用JDK动态代理

JDK Dynamic proxy can only proxy by interface (so your target class needs to implement an interface, which will also be implemented by the proxy class).

  1. <aop:aspectj-autoproxy proxy-target-class="true"/> 基于类,需要使用cglib库

CGLIB (and javassist) can create a proxy by subclassing. In this scenario the proxy becomes a subclass of the target class. No need for interfaces.

测试代码中是从过实现类来获取容器中对象,则需要使用cglib库,所以在proxy-target-class=”false”时会报错。

如果将测试代码中改为通过AccountService.class(接口)来获取bean.也可以正确运行。

学习过程中碰到的问题,顺便记录。

发表评论

表情:
评论列表 (有 0 条评论,118人围观)

还没有评论,来说两句吧...

相关阅读