SpringMVC
请求处理流程
看了很多介绍源码的文章,上来就是代码段劝退,别怕,虽然我也有代码段,但是肯定比他们少!
一些想法
我们一直在SpringMVC
这种框架里面写各种Controller
,标注各种@RequestMapping
,然后请求就能到指定的处理方法上了。这背后的逻辑,如果让我们实现应该怎么去弄?
他会不会像下面这样
- 根据请求地址找到处理方法
- 在调用处理方法前执行一些拦截逻辑
- 调用处理方法
- 根据处理方法所需要的各种参数,从请求中获取
- 根据处理方法的参数类型做转换
- 实际调用
- 在处理完成之后再执行一些拦截逻辑
- 处理返回值并返回
当然上面是最简单最基本的一个流程,SpringMVC
肯定也是这样做的,只是中间肯定多了非常多的一些其他逻辑,例如异常处理,静态资源处理,视图渲染等等
SpringMVC
是怎么做的?
跟我们想象的差不多,上面说的那些东西,在SpringMVC
里面都有对应的实现,我们用最朴素最简单的方式来介绍这些组件。当然,会非常不严谨,但不妨碍我们了解它的大概原理。
1、DispatcherServlet
前端控制器
这些事情的入口都发生在一个叫做
DispatcherServlet
的地方;并且按照我们一开始的设想,那些执行步骤都在这里体现到了。下面的代码是精简版,删了很多其他的逻辑,我们只关注我们需要关注的
doDispatch(HttpServletRequest processedRequest, HttpServletResponse response) throws Exception {
// 根据请求,拿到对应的handleChain(就是拦截器+Handle),里面就有我们写的Controller中的方法
HandlerExecutionChain mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 根据handle获取处理器适配器(为什么需要处理器适配器??后面会讲)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 执行前置拦截器,根据返回值true/false决定能不能继续
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 使用处理器适配器来实际调用handle
ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 执行后置拦截器
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 处理结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
2、HandlerMapping
根据请求找到对应的处理方式
没错,可以简单的将它理解成一个
Map<请求地址,handle>
的映射。只不过handle有很多种,所以HandlerMapping也有很多实现
public interface HandlerMapping {
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
3、HandlerExecutionChain
处理器执行链
Spring里面可以看见各种各样的
Chain
,这样做的好处就是在执行目标方法前后可以添加各种逻辑。而这里不直接调用目标handle的原因也是这样,可以应用我们写的各种HandlerInterceptor
;所以一个
HandlerExecutionChain
=handle
+List<HandlerInterceptor>
的组合。
public class HandlerExecutionChain {
private HandlerInterceptor[] interceptors;
// 遍历调用这些interceptors,执行他们的preHandle
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response){
// ....
}
// 也是遍历,调用postHandle
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv){
// ...
}
}
4、HandlerAdapter
处理器适配器
因为我们实际的
handle
可能是一个我们最经常使用的@Controller+@RequestMapping+Method的方式,也可能是一个org.springframework.web.servlet.mvc.Controller
的实现类,也可能是一个org.springframework.web.HttpRequestHandler
的实现类等,这两种我们平时很少接触到,虽然我们可以不用,但是框架不可能不支持啊。所以就会有各种各样的HandlerAdapter
`的子类来处理。
public interface HandlerAdapter {
// 资不资磁啊?
boolean supports(Object handler);
// 去实际调用handle并适配返回结果吧
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
// 无关紧要
long getLastModified(HttpServletRequest request, Object handler);
}
总结
很明显,这只是个大体的处理逻辑,其中的细节,每一个都能说很多,例如一个请求参数的封装逻辑都很复杂。
看到这里只要脑子里有个大体的印象,每个东西都是干嘛的,大体流程是怎么样的就行。后面细节我在一个一个的补充。说了这么多废话好像有人看一样