现在的位置: 首页 > 综合 > 正文

aop:config的proxy-target-class导致ClassCastException

2013年10月03日 ⁄ 综合 ⁄ 共 1489字 ⁄ 字号 评论关闭

aop:config的proxy-target-class导致ClassCastException  

先看一段代码:

1package com.test;
2public interface Movein {
3
4}

1package com.test;
2@Service(value="moveManager")
3@Transactional
4public class MoveManager implements Movein {
5
6}

在MoveAction中我们采用两种方式得到MoveManager 的对象:
第一种:用@Autowired注解自动注入

@Autowired
private MoveManager moveManager;

第二种:用ApplicationContext中的getBean()

ApplicationContext ctx = *************
MoveManager moveM = (MoveManager)ctx.getBean("moveManager");

 

采用第一种方法,当调用Action时会抛出类似的异常:BeanCreationException: Could not autowire field : private com.test.MoveManager  com.test.MoveAction.moveManager 

采用第二种方法,当执行MoveManager moveM = (MoveManager)ctx.getBean("moveManager");时会抛出类似的异 常:java.lang.ClassCastException: $Proxy40 cannot be cast to com.test.MoveManager 。把代码改为:Movein moveM = (Movein)ctx.getBean("moveManager"); 后运行正常,但这不是我想要的结果,我并不想改变强制转换类型。

现在来说说为什么会出现这种问题和解决方法。Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。默认情况如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目 标类型实现的接口都将被代理。 若该目标对象没有实现任何接口,则创建一个CGLIB代理。这就说明了为什么强制类型是MoveManager时会出现 ClassCastException异常而强制类型是Movein时运行正常,因为MoveManager被JDK代理。如果你希望在不改变代码的情况 下代理目标对象的所有方法,而不只是实现自接口的方法(强制使用CGLIB代理)只需要将<aop:config>的proxy-
target-class 属性设为true:

<aop:config proxy-target-class="true"/>


或者把Movein改成abstract类。

<aop:config proxy-target-class="true">
   <aop:pointcut id="insertNewsMethod" expression="execution(* com.yssoft.news.service.*.* (..))"/>
   <aop:advisor advice-ref="txAdvice" pointcut-ref="insertNewsMethod"/>
</aop:config>
proxy-target-class的默认值是false,所有导致
java.lang.ClassCastException: $Proxy0异常

设置为true即可

抱歉!评论已关闭.