一. 总体流程
1. checkMultipart 检查文件上传
检查当前请求Content-Type是否为Multipart/form-data,如果是则解析请求内的文件内容到MultipartHttpServletRequest包装类中
2. getHandler 获取处理器
在列表中(容器中实现了HandlerMapping接口的类)获取适合当前请求的Handler处理器
默认存在的Handler:
RequestMappingHandlerMapping(Controller核心处理器,优先级最高)
WelcomePageHandlerMapping(欢迎页处理器)
BeanNameUrlHandlerMapping(Bean名称路由匹配处理器)
RouterFunctionMapping(函数式路由处理器)
WelcomePageNotAcceptableHandlerMapping(页面无法解析406错误处理器)
SimpleUrlHandlerMapping(自定义路由处理器)
3. getHandlerAdapter 获取适配器
在列表中(容器中实现了HandlerAdapter接口的类)获取支持当前Handler的适配器
默认存在的HandlerAdapter
RequestMappingHandlerAdapter(Controller核心适配器,优先级最高)
HandlerFunctionAdapter(函数式处理器适配器)
HttpRequestHandlerAdapter(SPI普通适配器,通常不由用户使用)
SimpleControllerHandlerAdapter(自定义Handler适配器)
4. checkNotModified 检查是否修改
如果请求是GET或HEAD则检查内容是否被修改,如果没修改则不执行逻辑,直接返回304状态,前端会读取缓存
适配器实现了getLastModified方法,通过返回的值进行检查是否有修改
HttpRequestHandlerAdapter适配器并且Handler实现了LastModifed接口可使用
SimpleControllerHandlerAdapter适配器并且Handler实现了LastModifed接口可使用
5. HandlerInterceptor 执行拦截器
执行HandlerInterceptor拦截器preHandler方法
在步骤5、8、9中分别执行拦截器的preHandler、postHandler、afterCompletion方法
6. handle 执行处理器
获取HandlerMethod方法参数,从列表中(HandlerMethodArgumentResolver接口)获取合适的处理器对参数进行处理
通过HandlerMethod包装内的反射方法调用执行,并且在列表中(HandlerMethodReturnValueHandler接口)获取合适的返回值处理器进行处理
返回值处理器中再尝试从列表中(HttpMessageConverter接口)获取合适的消息转换器对返回值进行转换处理
7. Handle异步执行判断
通过HttpServletRequest.startAsync() 实现异步执行
如果Handler为异步处理则退出流程,不执行拦截器postHandler、afterCompletion方法,进入到步骤10,
8. HandlerInterceptor执行拦截器
执行HandlerInterceptor拦截器postHandler方法
9. processDispatchResult 处理返回
如果存在异常信息,则返回异常视图
render()进行视图渲染,从列表中(ViewResolver接口)获取合适的视图解析对视图进行解析,把ModelAndView中Model数据拆出来填充到View中
执行拦截器 afterCompletion方法,如果是异步则不执行
10. AsyncHandlerInterceptor执行拦截器
执行AsyncHandlerInterceptor拦截器的afterConcurrentHandlingStarted方法
11.CleanupMultipart 清理Multipart资源
清除解析出的文件内存信息
二.处理器、适配器的加载
在DispatchServlet类中initStrategies方法会对其初始化,从IOC容器中取出HandlerMapping类型或HandlerAdapter类型的Bean加入列表并且对其进行优先级排序,使用@Order注解的值越小优先级越高
三.拦截器的加载
拦截器通常是加载到处理器中,默认RequestMappingHandlerMapping处理器加载拦截器的位置处于WebMvcConfigurationSupport类requestMappingHandlerMapping方法
自定义拦截器可实现WebMvcConfigurer接口通过addInterceptors重写方法添加
同步拦截器HandlerInterceptor接口
异步拦截器AsyncHandlerInterceptor接口
四.参数处理器的加载
参数处理器在真正执行Handler之前会把方法参数拿出来处理一遍,默认RequestMappingHandlerAdapter适配加载参数处理器位置处于getDefaultArgumentResolvers方法
自定义参数加载器可实现WebMvcConfigurer接口通过addArgumentResolvers重写方法添加HandlerMethodArgumentResolver接口
五.返回值处理器的加载
返回值处理器是在Handle执行完对其返回值进行加工的处理器,默认RequestMappingHandlerAdapter从适配器中添加返回值处理器,位置处于WebMvcConfigurationSupport类requestMappingHandlerAdapter方法
自定义返回值处理器可实现WebMvcConfigurer接口通过addReturnValueHandlers重写方法添加HandlerMethodReturnValueHandler接口
六.消息转换器的加载
消息转换器是在返回值处理器中对返回到客户端的数据进行最后转换,默认RequestMappingHandlerAdapter从适配器中添加消息转换器,位置处于WebMvcConfigurationSupport类requestMappingHandlerAdapter方法
自定义消息转换器可实现WebMvcConfigurer接口通过configureMessageConverters重写方法添加HttpMessageConverter接口
七.视图解析器的加载
视图解析器是在处理器如果返回了视图则对其进行解析,默认视图解析器从IOC容器中取出ViewResolver类型的Bean加入列表并且对其进行优先级排序,使用@Order注解的值越小优先级越高