Spring Autowiring class vs. interface?

38,490

Normally, both will work, you can autowire interfaces or classes.

There's probably an autoproxy generator somewhere in your context, which is wrapping your boo bean in a generated proxy object. This proxy object will implement TheInterface, but will not be a TheClass. When using autoproxies, you need to program to the interface, not the implementation.

The likely candidate is transactional proxies - are you using Spring transactions, using AspectJ or @Transactional?

Share:
38,490

Related videos on Youtube

Marcus Leon
Author by

Marcus Leon

Director Clearing Technology, Intercontinental Exchange. Develop the clearing systems that power ICE/NYSE's derivatives markets.

Updated on January 01, 2020

Comments

  • Marcus Leon
    Marcus Leon over 4 years

    I have this Spring config:

    <bean id="boo" class="com.x.TheClass"/>
    

    The class TheClass implements TheInterface. Then I have this (hypothetical) Java code:

    @Autowired
    TheInterface x;
    
    @Autowired
    TheClass y;
    

    The autowiring of TheInterface works but the autowiring of TheClass fails. Spring gives me a NoSuchBeanDefinitionException for the class.

    Why can you wire the interface and not the class?

    • ptomli
      ptomli about 14 years
      Is there anything special about this class, like it being 'final', or having other instrumentation, like @Transactional, on it. You might be either missing an instrumentation lib, like CGLIB, or trying to create a subclass proxy on a final class.
  • skaffman
    skaffman about 14 years
    @Marcus: That's the problem then. If you use @Transactional and <tx:annotation-driven/>, you cannot cast the bean to MyClass, you have to use the interface.
  • Spanky Quigman
    Spanky Quigman over 12 years
    I know this is a bit old, but to add a bit here... You don't have to use the interface, but in order to autowire the class directly, you need to modify the <tx:annotation-driven /> configuration and add proxy-target-class="true" (this defaults to false). This lets you auto-wire directly to the class. Note that there can be weird side effects, e.g. I had used some reflection to find the parameterized type for a generic base class. The inheritance is changed due to the proxy class, so I had to take that into account. You can still wire by interface with proxy-target-class="true".
  • redochka
    redochka about 11 years
    @SpankyQuigman thank you. This was useful. @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)