SpringBoot请求映射原理
每个方法前的英文注解都挺重要的,可以了解整个方法的大致过程,事半功倍。
请求映射原理说难也不难,首先打开DispatcherServlet,毕竟这是mvc层最关键的功能,然后我们去查找doGet/doPost方法。所有的Servlet一般来说都是通过这两个方法进行请求。
但是我们没有找到
这是DispatcherServlet的hierarchy图,我们可以看到其继承和实现关系,如果没找到doGet,那就是默认继承了父类的,果然,我们子FrameworkServlet中找到了该方法
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
好吧,只有一个processRequest方法,让我们转到此方法
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
。。。。。
//以上都没有什么软用,都是对request请求进行一些包装等等,doService方法是最重要的
try {
doService(request, response);
}
。。。。
finally {
。。。。
}
}
点进去,没有实现?那应该是被他的子类实现,找他的子类,他的子类只有DispatcherServlet,果然找到了该方法,好吧,兜兜转转又回来了。然后又进行一些处理,doDispatch是关键的处理功能。
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
。。。
try {
doDispatch(request, response);
}
。。。
}
进入doDispatch源码,去除不重要的,功能主要通过getHandler实现,getHandler就是获取到对应的控制器映射。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// getHandler获取请求里面对应的控制器映射,查看getHandler
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
getHandler里重点是handlerMappings,这里包含了所有的映射,遍历所有映射去和请求里的method做匹配。匹配上了就返回。
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//handlerMappings里面储存的是所有的handlerMapping。
if (this.handlerMappings != null) {
//首先匹配请求的控制器映射,
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
handlerMappings里面的数据,0代表的是请求的控制器映射、1是欢迎页,根据名字也可以看出来。
这是RequestMappingHandlerMapping里的内容,所有的控制器的方法都在里面,并且注明了path。等下进行匹配时,就是先匹配pathLookup,再匹配方法,匹配成功后返回。