springmvc执行原理

springmvc执行原理,第1张

springmvc执行原理

大概流程:

初始化阶段:

在HttpServletBean调用init方法初始化,init方法里调用子类frameworkServlet的initServletBean方法,在调用

initWebApplicationContext方法,这个方法调用frameworkServlet子类DispatcherServlet的onRefresh方法,里面调用initStrategies进行初始化,主要初始化HandleMappings,handleAdapter,viewResolvers等。HandleMappings里有RequestMappingHandlerMapping(注解的方式就是这个,里面有mappingRegistry的mappingLookup里有请求路径对应哪个controller类的方法)

请求调用阶段:

   客户端发送http请求,服务端前端控制器(DispatcherServlet)收到请求,会执行doService方法(为啥是doService方法后面作解释),方法里会调用doDispatch方法去做真正处理,然后调用getHandler方法,先获取到合适的处理器映射器(HandlerMapping),然后在调用HandlerMapping的getHandler方法返回处理器执行器链(HandlerExecutionChain),处理器执行器链包含处理器和拦截器列表(前面初始化阶段已经初始化好),然后调用getHandlerAdapter方法获取处理器适配器HandlerAdapter,(会根据处理器handler匹配对应的HandlerAdapter);

接下来循环调用拦截器链中所有拦截器的前置处理mappedHandler.applyPreHandle(processedRequest, response);

然后接下来适配器HandlerAdapter调用真正的处理器方法

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

返回ModelAndView对象。

接下来循环调用拦截器链中所有拦截器的后置处理

mappedHandler.applyPostHandle(processedRequest, response, mv);

接下来调用方法进行视图解析和数据填充。

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

这个方法里调用render(mv, request, response);进行渲染视图;

视图解析器获取视图对象。

View view = viewResolver.resolveViewName(viewName, locale);

然后将视图进行数据填充

view.render(mv.getModelInternal(), request, response);

这个方法里设置响应头,返回给客户端。       
  prepareResponse(request, response);

  renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);

=============================================================

为啥是doService方法,其实应该是先调用frameworkServlet的service方法,service方法去调用父类HttpServlet的service方法,方法里会根据请求方式(get、post等)进行调用doGet,doPost等方法,这些方法里其实会去调用doService方法,DispatcherServlet是子类,实现了doService方法

springmvc实现controller方式有三种,一种是@Controller,一种是实现controller接口,还有一种是实现HttpRequestHandler接口。

实现controller接口的控制器适配器是SimpleControllerHandlerAdapter,

在ha.handle方法的时候,会强转Controller类,然后执行实现的方法handleReuqest方法里自己写好的逻辑,返回ModelAndView;

实现HttpRequestHandler接口的适配器是:HttpRequestHandlerAdapter ,在执行ha.handle方法的时候会强转HttpRequestHandler类,也是执行实现方法handleReuqest的自己写好逻辑,没有任何返回,需要request重新转发req.getrequestDispatcher;

@Controller方式的适配器默认是:AbstractHandlerMethodAdapter 实现类RequestMappingHandlerAdapter ,先在RequestMappingHandlerMapping根据请求路径url获取到对应的controller的方法,再会调用getMethodArgumentValues方法获取参数,然后调用doInvoke反射调用方法。

===============================================================

关于注解方式获取参数问题:

调用getMethodArgumentValues方法获取参数:

Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);

会根据参数形式获取对应的参数解析器:

@RequestParam或者不添加注解会用RequestParamMethodArgumentResolver解析器;@PathVariable会调用PathVariableMethodArgumentResolver解析器;

获取参数:

resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);

PathVariableMethodArgumentResolver解析器底层是使用servlet的

request.getAttribute("name")获取参数;

RequestParamMethodArgumentResolver解析器底层是使用servlet的

request.getParameterValues(name)、request.getParameterMap()方法获取参数;

关于spring和springmvc都去扫描类里的包,

如果同时扫描到controller目录下的类,会生成两次bean,所以spring需要扫描排除controller的类,springmvc要只扫描controller类。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5712489.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存