Vojtěch
Vojtěch

Reputation: 12416

Could not autowire field when bean implements some interface with Spring

I am using Spring in my Java Application, all the @Autowired annotations working until now.

Simplified example would be:

  @Component
  public class MyBean implements MyInterface {
      ...
  }

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

Once I try to start the Application, I get:

java.lang.IllegalArgumentException: Can not set MyBean field MyOtherBean.myBean to $ProxyXX

  1. The interface contains just two public simple methods and the class implements them.
  2. Both classes are public and have public default constructor. (I even tried to instantiate them in tests.
  3. Once I remove the implements section, everything works correctly.

What can be wrong with the implementation of the interface? What is $ProxyXX?

Upvotes: 5

Views: 6248

Answers (2)

Will Keeling
Will Keeling

Reputation: 23004

I suspect the issue is that Spring is injecting an AOP proxy which implements MyInterface - possibly for the purposes of transaction management or caching. Are any of MyBean's methods annotated @Transactional or annotated with any other annotation?

Ideally you'd probably want to reference MyBean by it's interface type - which should resolve the issue.

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

If you have more than one bean implementing MyInterface then you an always qualify your bean by name.

@Component
public class MyOtherBean {
    @Autowired
    @Qualifier("myBean")
    private MyInterface myBean;
    ...
}

Upvotes: 11

JB Nizet
JB Nizet

Reputation: 691735

By default, Spring uses Java dynamic proxies to implement AOP when the bean implements an interface. The easiest and cleanest way to solve your problem is to make program on interfaces, and inject theinterface insted of the concrete class:

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

See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#aop-proxying for how to force Spring to always use CGLib.

Upvotes: 4

Related Questions