spring - DispatcherServlet 如何准确地确定要调用哪个 Controller ?

标签 spring servlets model-view-controller dispatcher

假设我有一个用 @Controller 注释的类以及实例方法的相应映射,如下所示。

@Controller
@ResponseBody
public class UserController {

    @GetMapping("/example")
    public User fetchUserExample() {
        // ...
    }
}

另外,假设有 1000 个像上面这样具有不同 URL 映射的 Controller 。 我调用了任意 URL 和相应的 Controller ,并调用相应的方法并返回响应。

但我感到困惑的是,dispatcherServlet 到底如何知道在哪里可以找到所请求 URL 的方法?它是否会一一扫描每个 Controller 类以查找匹配项,并且是否对每个请求都执行此操作?如果是这样,这似乎并不是一个有效的方法。

我知道我们也可以对类进行注释,但这仍然不能回答问题,因为它仍然需要扫描类以进行匹配。

我希望它能够对 Controller 及其各自的映射进行某种跟踪。

我为此在 google 上搜索了很多,但几乎无论我走到哪里,都只浏览了表面,例如 @GetMapping、@RequestMapping 等注释告诉它要调用的方法。但我们知道这一点。 DispatcherServlet 首先如何精确定位该类,还是遵循我上面编写的方法?

一些网站提到了诸如 HandlerMapping、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter 之类的东西,但由于我是 Spring 新手,这些东西对我来说不明白它们是如何出现在此处的。

如有任何意见,我们将不胜感激。

最佳答案

由于映射注释是静态的,并且在运行时不会更改,因此每次处理请求时都不需要扫描每个 Controller 类来查找匹配的方法。只需在应用程序启动时扫描一次并将扫描结果存储到一种 map 中即可。因此,找到请求调用哪个方法只需从该映射中查找一些数据,这应该非常有效。

如果您对实际代码感兴趣,请查看RequestMappingHandlerMapping#lookupHandlerMethod()用于查找为请求调用哪个方法的逻辑。扫描结果存储到内部 MappingRegistry 中,lookupHandlerMethod() 将从中获取数据以查找匹配的方法。

您还可以尝试获取 RequestMappingHandlerMapping bean ,通过以下方式获取 MappingRegistry 的映射:

RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> handlerMethodMapping = mapping.getHandlerMethods();
handlerMethodMapping.forEach((k,v)->{
    System.out.println(k);
    System.out.println(v);
    System.out.println("-----");
});

它将打印出哪个 URL 请求映射到哪个处理程序方法。

关于spring - DispatcherServlet 如何准确地确定要调用哪个 Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59179214/

相关文章:

java.lang.NoClassDefFoundError : is coming in java servlets

java - Web应用程序中的并发控制

spring - 如果禁用Cookie,如何在Spring Security 3中重定向用户登录

java - 如何使用 Spring Data REST 公开可写的 REST api?

java - 如何使用 javascript 或 java 使用打印命令打印 JSP 页面中包含的表格?

Java为特定 session 变量配置超时

spring - Spring DOCTYPE 和 <beans> 标签的区别

php - 将应用程序与应用程序库、共享库、组件等分离

model-view-controller - 添加方法在所有 View 中可用

javascript - AngularJS 不更新 View