5

我在我的 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部分后,一切正常。

接口的实现可能有什么问题?是什么$ProxyXX

4

2 回答 2

11

我怀疑问题在于 Spring 正在注入一个 AOP 代理,该代理实现MyInterface- 可能是为了事务管理或缓存的目的。是否有任何MyBean's 方法被注释@Transactional或用任何其他注释注释?

理想情况下,您可能希望通过其接口类型引用 MyBean - 这应该可以解决问题。

@Component
public class MyOtherBean {
    @Autowired
    private MyInterface myBean;
    ...
}

如果您有多个 bean 实现MyInterface,那么您总是通过名称来限定您的 bean。

@Component
public class MyOtherBean {
    @Autowired
    @Qualifier("myBean")
    private MyInterface myBean;
    ...
}
于 2013-05-24T20:04:02.560 回答
4

默认情况下,当 bean 实现接口时,Spring 使用 Java 动态代理来实现 AOP。解决问题的最简单和最干净的方法是在接口上制作程序,并注入具体类的接口:

@Component
public class MyOtherBean {
    @Autowired
    private MyInterface myBean;
    ...
}

有关如何强制 Spring 始终使用 CGLib,请参阅http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#aop-proxying 。

于 2013-05-24T20:04:45.413 回答