SpringMVC 请求处理流程
一,如何进行初始化,初始化时做了什么,Filter和Servlet什么时候注入的?
1,springboot启动时onRefresh中会调用,ServletWebServerApplicationContext.createWebServer创建Tomcat
2,启动容器时触发TomcatStarter(实现了ServletContainerInitializer)onStartup方法初始化ServletContextInitializer接口的onStartup方法,第一步初始化内部ServletContextInitializer
第二步,通过ServletWebServerApplicationContext::selfInitialize(即ServletContextInitializer onStartup函数方法)找出FilterRegisterBean和ServletRegisterBean并完成初始化(即ServletContextInitializer onStartup函数方法),初始化FilterRegisterBean和ServletRegisterBean的时候springboot会调用tomcat相关包初始化到tomcat容器里(DIspatcherServlet就是从这里初始化进去的,DispatcherServlet的ServletRegisterBean声明在WebMVCAutoConfiguration里)
3,SpringBoot实例化bean后,AbstractHandlerMethodMapping通过InitializingBean的afterPropertiesSet进行RequestMapping检索供请求到达DispatcherServlet doDispatch方法是进行匹配对应HandlerMapping进行反射调用
二,一个请求如何从Tomcat到DispatcherServlet?
一个请求首先通过Socket接收到,进入Tomcat包中的Http11Processor service方法进行处理调用getAdapter().service(request,response),方法内调用postParseRequest(req,request,res,response)->connector.getService().getMapper().map(…,…,…)->internalMap(…)->internalMapWrapper(…)通过不同的Rule规则匹配请求的wrapper,然后通过wrapper进行调用创建filterchain最终调用到DispatcherServlet的doDispatch()方法,
三,一个请求如何从DispatcherServlet再到对应的RequestMapping做处理的?
首先找到匹配的handlerMapping
,在匹配能处理此handlermapping的handlerAdapter
,handlerAdapter通过HandlerMethodArgumentResolverComposite getArgumentResolver()找出支持处理的resolver,如果是@RequestBody则使用RequestResponseBodyMethodProcessor进行处理,调用HttpMessageConverter canread和read进行消息转换,通过反射机制调用Controller中对应的方法,最后通过HandlerMethodReturnValueHandlerComposite selectHandler()找出支持处理的HandlerMethodReturnValueHandler,如果是@ResponseBody则使用RequestResponseBodyMethodProcessor进行处理,调用HttpMessageConverter canwrite和write进行消息转换响应。
四,HandlerMapping和HandlerAdapter是如何加载的?
Tomcat包中的 StandardWrapperValve wrapper.allocate()中,DispatcherServlet init()的时候。优先获取WebMVCAutoConfiguration中配置,如果没有则获取webmvc中默认的策略
五,如何自定义mvc配置?
继承WebMvcConfigure进行配置,在DelegatingWebMvcConfiguration中会对自定义的WebMvcConfigure添加到WebMvcConfigureComposite进行多配置合并处理,通过WebMvcConfigurationSupport进行多配置获取。
文章内容可能不完全正确,如有错误请指出,谢谢