当bean实现与Spring的某些接口时,无法自动装配字段

时间:2013-05-24 18:09:07

标签: spring dependency-injection autowired

我在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

  1. 界面只包含两个公共简单方法,类实现它们。
  2. 这两个类都是公共的,并且具有公共默认构造函数。 (我甚至试图在测试中实例化它们。
  3. 删除implements部分后,一切正常。
  4. 接口的实现有什么问题?什么是$ProxyXX

2 个答案:

答案 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。