Spring @Autowired – Use interfaces!

Here’s a little lesson that I had to relearn today: When using Spring use interfaces.

The premise was I had a DAO bean that was configured with Spring, and it was @Autowired into my controller (or test case in this instance). Because I only intended to have a single implementation of this class, and because this was the first iteration of the project, I made the DAO bean concrete. However, when I tried to inject it into the test case got an exception:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
    No matching bean of type [userservices.jpa.TrackerEntryDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

This didn’t make any sense, but after I tried to extract the bean from the context it all became clear. The DAO object is wrapped in a @Transactional annotation, which causes the actual bean to be proxied (so the transaction can be managed). This means that the bean passed into the @Autowired variable isn’t of the concrete class anymore. But, if we are expecting an interface, then the proxy will also implement that interface.

This entry was posted in Spring. Bookmark the permalink.

One Response to Spring @Autowired – Use interfaces!

  1. Rob Murray says:

    Thanks, thinking about this enabled me to solve the problem I was having. My service layer should actually have been @Transactional instead of my Dao implementation. Switching these fixed this problem.

Leave a Reply