of type 'shiyaxin.service.impl.AccountServiceImpl' but was actually oftype 'com.sun.proxy.$Prox从根解决错
<!-- 配置aop建立日志类在指定方法(切面)执行之前执行-->
<aop:config >
<!-- 配置切面-->
<aop:aspect id="logAdvice" ref="logger">
<!-- 配置通知的类型,并且建立通知方法和切入点方法的关联-->
<aop:before method="printLog" pointcut="execution(public void com.shiyaxin.service.impl.AccountServiceImpl.saveAccount())"></aop:before>
</aop:aspect>
</aop:config>
我的解决办法是:学习Spring框架的时候,很容易犯下的一个错误,需要在配置文件中打开aop命名空间,并设置如下属性:
<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之后,结果运行成功了。总结一下原因如下:
<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).
<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.也可以正确运行。
学习过程中碰到的问题,顺便记录。
还没有评论,来说两句吧...