假设我有一个用@Controller注释的类以及此类实例方法的相应映射。
@Controller
@ResponseBody
public class UserController {
@GetMapping("/example")
public User fetchUserExample() {
// ...
}
}
也可以说,上面有1000个具有不同URL映射的控制器。我调用说是任何URL,并且找到了相应的控制器,并调用了相应的方法并返回了响应。
但是令我困惑的是,dispatcherServlet究竟如何确切知道在哪里可以找到所请求URL的方法?它是否逐个扫描每个控制器类以查找匹配项,并且是否针对每个请求执行此操作?如果是这样,那似乎并不是一种有效的方法。
我知道我们也可以注释该类,但这仍然不能回答问题,因为它仍然需要扫描这些类以查找匹配项。
我希望它将对控制器及其各自的映射保持某种跟踪。
我为此做了很多搜索,但是几乎我走到的任何地方都只掠过了表面,例如@GetMapping, @RequestMapping
之类的注释告诉它调用方法。但是我们知道。 dispatcherServlet首先是如何精确定位该类的,还是遵循我上面编写的方法?
[一些网站提到了HandlerMapping, SimpleControllerHandlerAdapter, RequestMappingHandlerAdapter
之类的东西,但是由于我是Spring的新手,所以这些东西对我来说是没有意义的。
任何输入将不胜感激。
由于映射注释是静态的,并且在运行时期间永远不会更改,因此它不需要扫描每个控制器类来为每个请求找到匹配的方法。只需在应用程序启动时对它们进行一次扫描,然后将扫描结果存储到某种地图中即可。因此,找到要为请求调用的方法只是从此映射中查找问题,这应该非常有效。
如果您对实际的代码感兴趣,请查看RequestMappingHandlerMapping#lookupHandlerMethod()
以了解查找请求中调用哪种方法的逻辑。扫描结果存储到内部RequestMappingHandlerMapping#lookupHandlerMethod()
,MappingRegistry
将从其中获取数据以查找匹配的方法。
您也可以尝试获取lookupHandlerMethod()
bean,通过以下方式获取RequestMappingHandlerMapping
的映射:
MappingRegistry
哪个将打印出哪个URL请求映射到哪个处理程序方法。