用户发送请求到执行controller方法的过程发生了什么

研究这个问题的意义是什么?该不会又是面试造火箭吧?

不,我想知道controller里的参数解析在哪里做的,为什么它能帮我们转为为bean

带着问题去找答案,过程如下:(springboot)

1.发送请求 /login

(1)域名解析。请求的URL是用域名标识的,比如taobao.com这 样,而HTTP网络通信需要得到IP地址才能建立连接,所以先要进行域名解析,访问域名解析服 务器DNS,得到域名的IP地址。

(2)经过CDN服务器的IP地址(Content Delivery Network,即内容分发网络)

cdn全称内容分布网络,就是将网站发布内容提前发送到距离用户最近的网络节点,这样用户上网就可以就近取得所需的内容,缩短用户访问网站的时间、提高访问成功率,保护源头网站不受攻击,解决了因为地域、带宽、运营商等问题,而造成用户访问网站延迟高或者无法访问,最终目标是提高用户上网体验,降低延迟,提升网速。

(3)经过微服务网关、负载均衡服务器

网关的基本功能: 智能路由:接收外部一切请求,并转发到后端的对外服务open-service上去; 注意:我们只转发外部请求,服务之间的请求不走网关。

(4)具体的应用服务器

2. servlet接收到请求

类名.方法名:DispatcherServlet.doDispatch()

3.找到映射器mappedHandler

类名.方法名: DispatcherServlet.doDispatch 
mappedHandler = this.getHandler(processedRequest);

 -----------------关于映射器-----------------------------

handlerMappings 是一个list存着:RequestMappingHandleMapping、WelcomPageHandleMapping等共5个映射列表

找到需要调用的那个controller对应的 handler

HandlerExecutionChain handler = mapping.getHandler(request);

最后我们返回的是RequestMappingHandleMapping里面对应的需要调用的controller

-----------------关于映射器 -----------------------------

4.找到适配器HandlerAdapter

类名.方法名:DispatcherServlet.doDispatch
 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

 -----------------关于映射器-------------------- 
通过上一步的HandlerExecutionChain对象,执行mappedHandler.getHandler()
可以得到Handler也就是HandleMethod对象 
handlerAdapters 适配器列表包括RequestMappingHandlerAdapter、HttpRequestHandlerAdapter等共4个适配器
 最后我们返回的是RequestMappingHandlerAdapter这个适配器
 -----------------关于映射器-------------------- 
疑问1:为什么需要适配器? 
答:映射器已经包含了controller信息,那么直接调用不就行了,为什么需要适配器?
很简单,映射器都分多个存储, 说明有不同类型的处理逻辑,那么就需要不同的适配器来处理不同的逻辑。 一般的请求对应的映射器是RequestMappingHandleMapping,适配器是RequestMappingHandlerAdapter。

5.调用handle准备执行controller

类名.方法名:DispatcherServlet.doDispatch 
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

6.调用前准备

参数解析,,找到了!!!!!!!!!!!!参数解析是在这里开始做的

类名.方法名:InvocableHandlerMethod.getMethodArgumentValues
 args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);

代码跟进

类名.方法名:AbstractNamedValueMethodArgumentResolver.resolveArgument
 Object arg = this.resolveName(resolvedName.toString(), nestedParameter, webRequest);

代码跟进:获取参数值

类名.方法名:RequestParamMethodArgumentResolver.resolveName
 String[] paramValues = request.getParameterValues(name);

代码跟进:调用controller

类名.方法名:InvocableHandlerMethod.invokeForRequest
 this.doInvoke(args);

总结:

到此,就从用户请求到外围的转发,再到具体的应用服务器,再到servlet接收,然后到spring里的映射器、适配器,然后是参数解析准备工作,最后调用controller具体的方法。

猜你喜欢

转载自blog.csdn.net/x18094/article/details/121492044