I hope you can help me with this.
I’m using Spring MVC (3.1.1) in my web application, and am facing a strange situation.
I have this simple @Controller, that makes use of the ServicioUsuario Service, and works fine:
@Controller
@RequestMapping("/ajax")
public class ControladorAjax extends ControladorGenerico {
@Autowired
ServicioUsuario servicioUsuario;
@RequestMapping("/check")
public ResponseEntity<String> check(@RequestParam String email) {
// Declarations and other operations omitted...
// Use servicioUsuario
servicioUsuario.doStuff();
return response;
}
}
However, if I remove the @Autowiring, and try to make Spring inject servicioUsuario as a parameter (i.e. by changing the method signature to: public ResponseEntity<String> check(@RequestParam String email, ServicioUsuario servicioUsuario)) the whole thing breaks, and I get this sort of exceptions in Tomcat’s log:
javax.servlet.ServletException: NestedServletException in java.lang.Thread.getStackTrace:: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.package.ServicioUsuario]: Specified class is an interface
I have these interfaces:
com.package
|-> Servicio.java (interface)
|-> ServicioUsuario.java (interface that extends Servicio)
and these clases:
com.package.impl
|-> ServicioImpl.java (implements Servicio)
|-> ServicioUsuarioImpl.java (@Service("servicioUsuario") that extends ServicioImpl implements ServicioUsuario)
and configured Spring to scan both packages with:
<context:component-scan base-package="com.package
com.package.impl" />
Why is Spring trying to instantiate the interface and not the implementing class? Is it something I’m doing wrong?
According to 16.3.3.1 Supported method argument types of the official documentation, this is a complete list of what controller methods can take:
As you can see, Spring beans are not on this (quite impressive) list. Why would you inject services via controller method? They never change. It’s enough to inject them once and assign them to a field.