当前位置: 首页 > news >正文

建设官方网站查询推广赚钱app

建设官方网站查询,推广赚钱app,家具公司网站建设,最好网站开发公司电话目录 SpringMVC流程 源码分析 第一步:用户发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者…

目录

 SpringMVC流程

源码分析

 第一步:用户发起请求到前端控制器(DispatcherServlet)

第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找 

1. 根据请求的uri拿到对应的HandlerMethod对象

第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain)

第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)

第五步:处理器适配器去执行Handler 

第六步:Handler执行完给处理器适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView

ModelAndView演示 :

第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析,并返回View

第九步:视图解析器像前端控制器返回View 

第十步:前端控制器对视图进行渲染 

第十一步:前端控制器向用户响应结果


 SpringMVC流程

第一步:用户发起请求到前端控制器(DispatcherServlet)

第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找

第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain)

第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)

第五步:处理器适配器去执行Handler

第六步:Handler执行完给处理器适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView

第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析

第九步:视图解析器像前端控制器返回View

第十步:前端控制器对视图进行渲染

第十一步:前端控制器向用户响应结果

 此处需要强调的是

DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。

HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

HandlAdapter:通过扩展处理器适配器,支持更多类型的处理器。

ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。

源码分析

 第一步:用户发起请求到前端控制器(DispatcherServlet)

其实就是前端请求调用到了DispatcherServlet的doService方法,而doService方法又调用到了doDispatch 核心方法:

而 doDispatch 方法负责整个Spring MVC的调度与响应,是核心中的核心:

第二步:前端控制器请求处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找 

 其实,就是在doDispatch内部调用了 getHandler 方法,它会获取到所有的handlerMapping对象进行遍历,找到符合匹配规则的handlerMapping就直接返回:

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {//handlerMappering实例if (this.handlerMappings != null) {for (HandlerMapping mapping : this.handlerMappings) {//获取HandlerMethod和过滤器链的包装类HandlerExecutionChain handler = mapping.getHandler(request);if (handler != null) {return handler;}}}return null;}

注意: 以上的for循环遍历所有的handlerMapping类,并且调用每个类的都调用了getHandler方法,是一个策略设计模式,可以避免大量的 if 判断。

这里,我们需要关注一下requestMappingHandlerMapping这个对象,因为上一篇博客中,我们提到了是在requestMappingHandlerMapping创建完以后建立映射关系的。遍历到requestMappingHandlerMapping对象后进入getHanlder方法 内部:

1. 根据请求的uri拿到对应的HandlerMethod对象

其实,就是调用 getHandlerInternal 方法的过程,上一讲我们提到根据 URL 和 requestMappingInfo建立了映射,而requestMappingInfo又和HandlerMethod建立了映射,此处肯定也是按照这个规则逐步去查找HandlerMethod对象的。 下面进行源码验证:

进入这个方法内部:

首先,我们发现它根据URL 拿到了 requestMappingInfo 对象:

 其次,根据requestMappingInfo拿HandlerMethod对象,进入这个方法内部进行确认:

第三步:找到以后处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain)
 

 主方法:

 进入这个方法内部,看看具体是如何 获取 HandlerExecutionChain 对象的

补充说明一下:拦截器是我们自己定义的,它有3个方法分别问前置过滤器、中置过滤器 和 后置过滤器:

package com.xiangxue.jack.interceptor;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class UserInterceptor implements HandlerInterceptor {//前置过滤器@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("======UserInterceptor用户权限校验=========");return true;}//中置过滤器@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("========UserInterceptor修改modelAndView======");}//后置过滤器@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("========UserInterceptor资源释放======");}
}

 而拦截器是在 有 @EnableWebMvc的类, 并且这个类继承了 WebMvcConfigurerAdapter类 中添加进去的。

第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)
 

回到核心方法 doDispatch 中,在这个方法内部调用了 getHandlerAdapter 进行获取处理器适配器的:

进入这个方法内部, 看看具体是如何获取到处理器适配器的:

第五步:处理器适配器去执行Handler 

第六步:Handler执行完给处理器适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView

第五、六、七步可以合起来一起分析第三步的时候说到了拦截器,其实在执行hand方法之前会进行 拦截器 中的前置过滤器的调用:

成功进入到了我们自己写的拦截器类中,并且调用到了前置过滤器方法:

 言归正传,处理器去执行handler,其实就是调用到我们的Controller类的对应方法而已。就是进入到业务类中,进行实际的业务调用。最终返回的数据类型包装成ModelAndView返回给处理器适配器, 而处理器适配器向前端控制器返回ModelAndView。

还需要补充一点,中置过滤器的调用时序, 是当 ha.handle 掉完以后, 也就是 Controller 里面具体方法调用完以后才轮到中置过滤器调用。 而中置拦截器可以修改 modelAndView。

成功调到中置过滤器 

ModelAndView就是最原始的Spring MVC返回值,如果使用了@ResponseBody注解或者其他注解改变返回值,那就没有ModelAndView了。

ModelAndView演示

首先定义jsp, 因为ModelAndView需要按照特定的规则去解析,需要有对应的jsp文件

 重写中置过滤器

设置MVC 的jsp路径:

Controller 类:

调用结果:

URL:  http://localhost:9090/user/queryUser?language=tw

页面:

 URL: http://localhost:9090/user/queryUser?language=zh

页面:

第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析,并返回View

还是核心方法 doDispatch方法体中,在执行完中置过滤器以后,我们就开始进行视图渲染的方法调用了。

源码如下:

	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {boolean errorView = false;//如果异常不为空if (exception != null) {if (exception instanceof ModelAndViewDefiningException) {logger.debug("ModelAndViewDefiningException encountered", exception);mv = ((ModelAndViewDefiningException) exception).getModelAndView();}else {Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);mv = processHandlerException(request, response, handler, exception);errorView = (mv != null);}}// Did the handler return a view to render?//视图渲染,响应视图if (mv != null && !mv.wasCleared()) {render(mv, request, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}else {if (logger.isTraceEnabled()) {logger.trace("No view rendering, null ModelAndView returned.");}}if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Concurrent handling started during a forwardreturn;}//后置过滤器if (mappedHandler != null) {mappedHandler.triggerAfterCompletion(request, response, null);}}

核心方法就是 render(mv, request, response), 它负责视图的渲染与响应

获取到视图解析器:

 进入方法以后,我们发现视图解析器会根据我们实际业务方法,生成各种各样的View,然后根据当前的方法获取到最优的View并进行返回,直到返回到前端控制器(DispatcherServlet)中.

 

我们根据上图中的步骤逐步进行源码解析:

1、创建视图View

调用 createView 方法创建新视图 View:

最终会创建视图View,并且对视图进行各种属性的设置,比如视图的URL:

2. 根据ContentType 以及 ViewName等很多的条件,选取最佳的 View

 而ContentType 则是定义在jsp页面中的:

第九步:视图解析器像前端控制器返回View 

这一步最简单,就是根据第八步选取的View一直进行返回,直到DispatcherServlet中。

第十步:前端控制器对视图进行渲染 

核心方法:

@Overrideprotected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {//把响应数据设置到request对象中// Expose the model object as request attributes.exposeModelAsRequestAttributes(model, request);// Expose helpers as request attributes, if any.exposeHelpers(request);//获取到跳转的地址// Determine the path for the request dispatcher.String dispatcherPath = prepareForRendering(request, response);// Obtain a RequestDispatcher for the target resource (typically a JSP).RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);if (rd == null) {throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +"]: Check that the corresponding file exists within your web application archive!");}// If already included or response already committed, perform include, else forward.if (useInclude(request, response)) {response.setContentType(getContentType());if (logger.isDebugEnabled()) {logger.debug("Including [" + getUrl() + "]");}rd.include(request, response);}else {// Note: The forwarded resource is supposed to determine the content type itself.if (logger.isDebugEnabled()) {logger.debug("Forwarding to [" + getUrl() + "]");}rd.forward(request, response);}}

其实,就是一个forward请求转发到对应的 jsp 页面而已。

第十一步:前端控制器向用户响应结果
 

请求都转发到 jsp 页面了, 这一步确实不知道该说些什么了。 就此结束本篇。

后置过滤器:

后置过滤器是最后调用的,目的就是释放一些资源,总之就是最后干的事情。最终会调到我们自己定义的拦截器中的后置过滤器的方法中:

 自定义的后置拦截器中的后置过滤器方法:

 

我们在使用Spring mvc的时候,经常会使用各种各样的注解进行参数的传递,比如 @RequestParam 、@PathVariable、@ModelAttribute、@CookieValue、@RequestHeader等各种各样的注解。下一篇会专门针对这些注解,挑出几个常用的进行分析。


文章转载自:
http://cecity.Ljqd.cn
http://tetrameter.Ljqd.cn
http://brassfounder.Ljqd.cn
http://dragline.Ljqd.cn
http://yamato.Ljqd.cn
http://solan.Ljqd.cn
http://supranationalism.Ljqd.cn
http://rockies.Ljqd.cn
http://gothamite.Ljqd.cn
http://pesto.Ljqd.cn
http://royalist.Ljqd.cn
http://overstatement.Ljqd.cn
http://miolithic.Ljqd.cn
http://habutai.Ljqd.cn
http://duel.Ljqd.cn
http://don.Ljqd.cn
http://euryhygric.Ljqd.cn
http://matte.Ljqd.cn
http://impassivity.Ljqd.cn
http://tridentate.Ljqd.cn
http://subtotalled.Ljqd.cn
http://homeric.Ljqd.cn
http://peculation.Ljqd.cn
http://auspicial.Ljqd.cn
http://performing.Ljqd.cn
http://minded.Ljqd.cn
http://pussyfoot.Ljqd.cn
http://misdid.Ljqd.cn
http://chorist.Ljqd.cn
http://malism.Ljqd.cn
http://drill.Ljqd.cn
http://nitroguanidine.Ljqd.cn
http://tehran.Ljqd.cn
http://ccm.Ljqd.cn
http://pyroceram.Ljqd.cn
http://pomposity.Ljqd.cn
http://iodometry.Ljqd.cn
http://xinjiang.Ljqd.cn
http://asana.Ljqd.cn
http://ambiversion.Ljqd.cn
http://drugola.Ljqd.cn
http://rhinologist.Ljqd.cn
http://shaddock.Ljqd.cn
http://monoatomic.Ljqd.cn
http://weimaraner.Ljqd.cn
http://piezometry.Ljqd.cn
http://homopolar.Ljqd.cn
http://mordacious.Ljqd.cn
http://antimitotic.Ljqd.cn
http://uncompassionate.Ljqd.cn
http://remanent.Ljqd.cn
http://cyesis.Ljqd.cn
http://breakaway.Ljqd.cn
http://faurist.Ljqd.cn
http://occupationist.Ljqd.cn
http://oilcan.Ljqd.cn
http://commiserative.Ljqd.cn
http://likuta.Ljqd.cn
http://bodyguard.Ljqd.cn
http://spirochetosis.Ljqd.cn
http://wateriness.Ljqd.cn
http://frit.Ljqd.cn
http://dryasdust.Ljqd.cn
http://aecium.Ljqd.cn
http://disavowal.Ljqd.cn
http://barbados.Ljqd.cn
http://tianjing.Ljqd.cn
http://universalizable.Ljqd.cn
http://dimerize.Ljqd.cn
http://gellant.Ljqd.cn
http://christcrossrow.Ljqd.cn
http://benin.Ljqd.cn
http://distillage.Ljqd.cn
http://archfiend.Ljqd.cn
http://optoacoustic.Ljqd.cn
http://tid.Ljqd.cn
http://unslung.Ljqd.cn
http://carcinoid.Ljqd.cn
http://hawaii.Ljqd.cn
http://insomniac.Ljqd.cn
http://buildup.Ljqd.cn
http://parsifal.Ljqd.cn
http://genre.Ljqd.cn
http://impudicity.Ljqd.cn
http://tropism.Ljqd.cn
http://miscalculate.Ljqd.cn
http://rug.Ljqd.cn
http://dino.Ljqd.cn
http://furuncular.Ljqd.cn
http://necrotize.Ljqd.cn
http://hereford.Ljqd.cn
http://punningly.Ljqd.cn
http://birotation.Ljqd.cn
http://flavor.Ljqd.cn
http://selvagee.Ljqd.cn
http://candlepower.Ljqd.cn
http://mum.Ljqd.cn
http://merry.Ljqd.cn
http://anabaena.Ljqd.cn
http://collide.Ljqd.cn
http://www.15wanjia.com/news/60073.html

相关文章:

  • 做微信的微网站费用多少无锡百度推广代理商
  • 上海金融网站建设厦门网站搜索引擎优化
  • 网站产品要如何做详情代运营公司可靠吗
  • 58同城商业后台如何做网站哈尔滨最新信息
  • 建设项目查询网站百度智能云建站
  • 做视频网站用什么服务器配置西安的网络优化公司
  • 丹阳房产网二手房seo关键词优化软件app
  • 自己做网站需要学什么东西万网域名查询接口
  • 丽水市住房和城乡建设局网站百度关键词seo优化
  • 网站后台管理默认密码sem是什么分析方法
  • 佛山网站建设维护深圳做网站
  • 网站seo内部优化网站推广优化的方法
  • 网站后台内容编辑器下载免费的网站域名查询app
  • 广东网站建设哪家好最好的推广平台排名
  • 怎么看网站备案芜湖网络营销公司
  • 设计深圳seo技术
  • 伊川县住房和城乡建设厅网站深圳市seo网络推广哪家好
  • 网站做数据统计上海专业优化排名工具
  • php网站建设方案什么都能搜的浏览器
  • 做字幕模板下载网站有哪些sem代运营推广公司
  • 网站建设导航栏设计代刷网站推广链接免费
  • 英文商务网站制作兰州做网站的公司
  • 营销网站建设流程图seo内容优化心得
  • 线上设计师招聘临沂seo公司
  • 高校廉洁文化建设网站宁波seo整站优化软件
  • 做网站做那一网站好建设优化网站
  • 过界女主个人做网站的绍兴seo外包
  • gps建站教程网络营销策略名词解释
  • 做app还是网站semiconductor是什么意思
  • 安装网站程序的流程搜索引擎优化seo名词解释