我在Java应用程序中使用Spring,所有@Autowired注释一直工作到现在。
简化的例子是:
@Component
public class MyBean implements MyInterface {
...
}
@Component
public class MyOtherBean {
@Autowired
private MyBean myBean;
...
}
一旦我尝试启动应用程序,我得到:
java.lang.IllegalArgumentException: Can not set MyBean field MyOtherBean.myBean to $ProxyXX
implements
部分后,一切正常。接口的实现有什么问题?什么是$ProxyXX
?
答案 0 :(得分:11)
我怀疑问题是Spring正在注入一个实现MyInterface
的AOP代理 - 可能是出于事务管理或缓存的目的。是MyBean
的任何方法是注释@Transactional
还是使用任何其他注释注释?
理想情况下,您可能希望通过它的接口类型引用MyBean - 这应该可以解决问题。
@Component
public class MyOtherBean {
@Autowired
private MyInterface myBean;
...
}
如果你有多个bean实现MyInterface
,那么你总是按名称限定你的bean。
@Component
public class MyOtherBean {
@Autowired
@Qualifier("myBean")
private MyInterface myBean;
...
}
答案 1 :(得分:4)
默认情况下,当bean实现接口时,Spring使用Java动态代理来实现AOP。解决问题最简单,最干净的方法是在接口上创建程序,并注入具体类的接口:
@Component
public class MyOtherBean {
@Autowired
private MyInterface myBean;
...
}
请参阅http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#aop-proxying了解如何强制Spring始终使用CGLib。