0

我希望你能帮我解决这个问题。

我在我的 web 应用程序中使用 Spring MVC (3.1.1),并且面临一个奇怪的情况。我有这个简单的@Controller,它利用了 ServicioUsuario 服务,并且工作正常:

@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;
  }
}

但是,如果我删除了@Autowiring,并尝试将 Spring 注入servicioUsuario作为参数(即通过将方法签名更改为:),public ResponseEntity<String> check(@RequestParam String email, ServicioUsuario servicioUsuario)整个事情就会中断,并且我在 Tomcat 的日志中得到了这种异常:

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

我有这些接口:

com.package
  |-> Servicio.java (interface)
  |-> ServicioUsuario.java (interface that extends Servicio)

和这些类:

com.package.impl
  |-> ServicioImpl.java (implements Servicio)
  |-> ServicioUsuarioImpl.java (@Service("servicioUsuario") that extends ServicioImpl implements ServicioUsuario)

并配置 Spring 以扫描两个包:

<context:component-scan base-package="com.package
                                      com.package.impl" />

为什么 Spring 试图实例化接口而不是实现类?是我做错了什么吗?

4

1 回答 1

5

根据官方文档的16.3.3.1 Supported method argument types,这是控制器方法可以采用的完整列表:

  • 请求或响应对象(Servlet API)。[...] 例如ServletRequestHttpServletRequest.

  • 会话对象(Servlet API):类型为HttpSession.

  • org.springframework.web.context.request.WebRequestorg.springframework.web.context.request.NativeWebRequest

  • java.util.Locale对于当前的请求语言环境 [...]

  • java.io.InputStream/java.io.Reader用于访问请求的内容。[...]

  • java.io.OutputStream/java.io.Writer用于生成响应的内容。[...]

  • java.security.Principal包含当前经过身份验证的用户。

  • @PathVariable用于访问 URI 模板变量的注释参数。[...]

  • @RequestParam用于访问特定 Servlet 请求参数的注释参数。[...]

  • @RequestHeader用于访问特定 Servlet 请求 HTTP 标头的注释参数。[...]

  • @RequestBody用于访问 HTTP 请求正文的注释参数。[...]

  • @RequestPart用于访问“multipart/form-data”请求部分内容的注释参数。[...]

  • HttpEntity<?>用于访问 Servlet 请求 HTTP 标头和内容的参数。[...]

  • java.util.Map// org.springframework.ui.Model[ org.springframework.ui.ModelMap...]

  • org.springframework.web.servlet.mvc.support.RedirectAttributes[...]

  • 命令或表单对象将请求参数绑定到 bean 属性(通过设置器)或直接绑定到字段,[...]

  • org.springframework.validation.Errors/ org.springframework.validation.BindingResult[...]

  • org.springframework.web.bind.support.SessionStatus[...]

  • org.springframework.web.util.UriComponentsBuilder[...]

如您所见,Spring bean 不在这个(相当令人印象深刻的)列表中。为什么要通过控制器方法注入服务?他们从不改变。将它们注入一次并将它们分配给一个字段就足够了。

于 2012-11-10T15:10:47.550 回答