先看一段代码:
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类。
posted on 2009-11-11 10:49
...... 阅读(467)
评论(0) 编辑 收藏 所属分类:
SPRING