安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

SpringMVC请求流程源码分析

1月25日 心碎巷投稿
  一、SpringMVC使用1。工程创建创建maven工程。添加java、resources目录。引入Springwebmvc依赖。dependencygroupIdorg。springframeworkgroupIdspringwebmvcartifactIdversion5。3。4versiondependency删除srcmainwebappWEBINFweb。xml配置文件。从tomcat的示例工程中找一份web。xml替换,这里推荐从webappsROOTWEBINF中拿,并且在其中添加context的监听器和servlet配置,配置如下。!Context加载监听器listenerlistenerclassorg。springframework。web。context。ContextLoaderListenerlistenerclasslistenerservletservletnamedispatcherServletservletnameservletclassorg。springframework。web。servlet。DispatcherServletservletclassinitparamparamnamecontextConfigLocationparamnameparamvalueclasspath:application。xmlparamvalueinitparam!Web服务器一旦启动,Servlet就会实例化创建对象,然后初始化(预备创建对象)loadonstartup1loadonstartupservletservletmappingservletnamedispatcherServletservletnameurlpatternurlpatternservletmapping在resources目录中创建springmvc。xml文件,并添加如下配置:?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexmlns:contexthttp:www。springframework。orgschemacontextxmlns:mvchttp:www。springframework。orgschemamvcxsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdhttp:www。springframework。orgschemacontexthttp:www。springframework。orgschemacontextspringcontext。xsdhttp:www。springframework。orgschemamvchttps:www。springframework。orgschemamvcspringmvc。xsd!配置spring包扫描路径,被Component、Controller、Service、Repository标注的类都会交由Spring托管一个Beancontext:componentscanbasepackagecom。ybe。!配置视图解析器beanclassorg。springframework。web。servlet。view。InternalResourceViewResolverpropertynameprefixvaluepropertynamesuffixvalue。jsppropertybeanbeans在srcmainwebappWEBINF下添加applicationContext。xml文件,配置如下:?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexmlns:contexthttp:www。springframework。orgschemacontextxmlns:mvchttp:www。springframework。orgschemamvcxsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdhttp:www。springframework。orgschemacontexthttp:www。springframework。orgschemacontextspringcontext。xsdhttp:www。springframework。orgschemamvchttps:www。springframework。orgschemamvcspringmvc。xsdbeans创建Controller类,代码如下:packagecom。ybe。importorg。springframework。stereotype。Cimportorg。springframework。web。bind。annotation。RequestMControllerpublicclassHelloController{RequestMapping(hello)publicStringhelloWorld(){System。out。println(helloworld);}}2。工程配置点击AddConfigurations或者RunAddConfigurations。配置本地tomcat的目录配置浏览器地址,点击上图左上角的号,选择TomcatServer选项后,点击Deployment选项,点击右边的号。选择Artifacts后,选择springMvcTest:war。3。启动工程
  二、SpringMVC启动过程
  SpringMVC是依赖Java的Web容器技术,整个springmvc的启动过程是建立在Servlet技术基础上的。SpringMVC借助Web容器和Servelt的生命周期进行了扩展。父容器的初始化在ContextLoaderListener类中initWebApplicationContext方法进行,子容器的初始化在DispatcherServlet中init方法中进行。1。父容器启动过程
  如果web。xml中配置了ContextLoaderListener监听器,则web容器启动的时候先会调用监听器ContextLoaderListener的initWebApplicationContext方法。整个过程如下图:
  initWebApplicationContext中的整个过程就是创建了一个spring容器(父容器),并且根据springApplication。xml的配置内容往Spring容器中注入Bean对象。最后把spring容器(this。context对象)放入serveltContext的属性中。2。子容器启动过程(SpringMvc容器)
  DispatcherServlet是在web。xml配置文件中配置的Servlet类,是SpringMVC的请求分发核心类。所有的请求都由DispatcherServlet去分发处理。
  DispatcherServlet的继承关系如下图:
  上图可知DispatcherServlet继承了HttpServletBean。在HttpServletBean中重写了init(),Web容器启动的时候会根据配置文件中定义的Servlet进行创建,并且会根据配置项(loadonstartup)觉定在什么时候调用Servlet的init方法,init方法在整个Servlet的生命周期中只会调用一次。初始化init方法的主体实现过程如下:
  1。WebApplicationContextUtils。getWebApplicationContext(getServletContext())从ServletContext中获取属性为WebApplicationContext。ROOTWEBAPPLICATIONCONTEXTATTRIBUTE的对象,即Spring父容器对象。
  2。wac。addApplicationListener(newSourceFilteringListener(wac,newContextRefreshListener())),给子容器添加应用监听器,该监听器在后面的finishRefresh()方法中进行触发,方法里面封装了初始化SpringMVC中九大组件的逻辑。
  3。publishEvent(newContextRefreshedEvent(this))发布Context刷新事件,会触发SourceFilteringListener监听器,最终进行initStrategies的调用。3。九大组件的初始化
  initStrategies是SpringMVC中九大组件的初始化方法其中9个方法对应9个组件的初始化,本文中只讲映射器和适配器的创建过程,initStrategies代码如下:初始化MultipartResolver:主要用来处理文件上传。如果定义过当前类型的bean对象,那么直接获取,如果没有的话,可以为nullinitMultipartResolver(context);初始化LocaleResolver:主要用来处理国际化配置,基于URL参数的配置(AcceptHeaderLocaleResolver),基于session的配置(SessionLocaleResolver),基于cookie的配置(CookieLocaleResolver)initLocaleResolver(context);初始化ThemeResolver:主要用来设置主题ThemeinitThemeResolver(context);初始化HandlerMapping:映射器,用来将对应的request跟controller进行对应initHandlerMappings(context);初始化HandlerAdapter:处理适配器,主要包含Http请求处理器适配器,简单控制器处理器适配器,注解方法处理器适配器initHandlerAdapters(context);初始化HandlerExceptionResolver:基于HandlerExceptionResolver接口的异常处理initHandlerExceptionResolvers(context);初始化RequestToViewNameTranslator:当controller处理器方法没有返回一个View对象或逻辑视图名称,并且在该方法中没有直接往response的输出流里面写数据的时候,spring将会采用约定好的方式提供一个逻辑视图名称initRequestToViewNameTranslator(context);初始化ViewResolver:将ModelAndView选择合适的视图进行渲染的处理器initViewResolvers(context);初始化FlashMapManager:提供请求存储属性,可供其他请求使用initFlashMapManager(context);1。处理器映射器的初始化
  1。initHandlerMappings初始化映射器,在此方法中第一步会获取容器中实现了HandlerMapping的Bean对象,如果有则用自定义的HandlerMapping实现类作为this。handlerMappings的值;如果没有自定义类,则获取SpringMVC预先定义好的策略类。代码流程如下:
  2。ClassPathResourceresourcenewClassPathResource(DEFAULTSTRATEGIESPATH,DispatcherServlet。class);获取DispatcherServlet。properties资源文件,位置在springwebmvc中,路径resourcesorgspringframeworkwebservletDispatcherServlet。properties,该资源文件中定义了SpringMVC组件的默认实现策略类,具体内容如下:DefaultimplementationclassesforDispatcherServletsstrategyinterfaces。UsedasfallbackwhennomatchingbeansarefoundintheDispatcherServletcontext。Notmeanttobecustomizedbyapplicationdevelopers。org。springframework。web。servlet。LocaleResolverorg。springframework。web。servlet。i18n。AcceptHeaderLocaleResolverorg。springframework。web。servlet。ThemeResolverorg。springframework。web。servlet。theme。FixedThemeResolverorg。springframework。web。servlet。HandlerMappingorg。springframework。web。servlet。handler。BeanNameUrlHandlerMapping,org。springframework。web。servlet。mvc。method。annotation。RequestMappingHandlerMapping,org。springframework。web。servlet。function。support。RouterFunctionMappingorg。springframework。web。servlet。HandlerAdapterorg。springframework。web。servlet。mvc。HttpRequestHandlerAdapter,org。springframework。web。servlet。mvc。SimpleControllerHandlerAdapter,org。springframework。web。servlet。mvc。method。annotation。RequestMappingHandlerAdapter,org。springframework。web。servlet。function。support。HandlerFunctionAdapterorg。springframework。web。servlet。HandlerExceptionResolverorg。springframework。web。servlet。mvc。method。annotation。ExceptionHandlerExceptionResolver,org。springframework。web。servlet。mvc。annotation。ResponseStatusExceptionResolver,org。springframework。web。servlet。mvc。support。DefaultHandlerExceptionResolverorg。springframework。web。servlet。RequestToViewNameTranslatororg。springframework。web。servlet。view。DefaultRequestToViewNameTranslatororg。springframework。web。servlet。ViewResolverorg。springframework。web。servlet。view。InternalResourceViewResolverorg。springframework。web。servlet。FlashMapManagerorg。springframework。web。servlet。support。SessionFlashMapManager
  由内容可知HandlerMapping预制的策略类有BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、RouterFunctionMapping,其中RequestMappingHandlerMapping是我们常用的HandlerMapping对象。
  3。RequestMappingHandlerMapping的初始化,因为RequestMappingHandlerMapping实现了InitializingBean接口,所以在容器中初始化完之后会执行afterPropertiesSet方法,其中会调用super。afterPropertiesSet();父类为AbstractHandlerMethodMapping。此方法中会调用initHandlerMethods(),代码如下:protectedvoidinitHandlerMethods(){遍历Bean,逐个处理for(StringbeanName:getCandidateBeanNames()){排除目标代理类,AOP相关,可查看注释if(!beanName。startsWith(SCOPEDTARGETNAMEPREFIX)){处理BeanprocessCandidateBean(beanName);}}初始化处理器的方法们,目前没有特殊业务逻辑,只是打印ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志ahandlerMethodsInitialized(getHandlerMethods());}
  4。processCandidateBean方法中会判断BeanName的Bean是否有Controller。class或者RequestMapping。class注解来生成具体的HandlerMethod对象。2。处理器适配器的初始化
  1。initHandlerAdapters适配器初始化,过程和映射器相似。从上面的内容可知HandlerAdapter与之的策略类有HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter、HandlerFunctionAdapter。其中RequestMappingHandlerAdapter是我们常用的处理器适配器。
  2。RequestMappingHandlerAdapter实现了InitializingBean接口,在容器中初始化完之后会调用afterPropertiesSet方法,在此方法中会初始化参数解析器、绑定参数解析器、返回值解析器。此方法代码如下:OverridepublicvoidafterPropertiesSet(){Dothisfirst,itmayaddResponseBodyadvicebeans初始化注释了ControllerAdvice的类的相关属性initControllerAdviceCache();初始化argumentResolvers属性if(this。argumentResolversnull){ListHandlerMethodArgumentResolverresolversgetDefaultArgumentResolvers();this。argumentResolversnewHandlerMethodArgumentResolverComposite()。addResolvers(resolvers);}初始化initBinderArgumentResolvers属性if(this。initBinderArgumentResolversnull){ListHandlerMethodArgumentResolverresolversgetDefaultInitBinderArgumentResolvers();this。initBinderArgumentResolversnewHandlerMethodArgumentResolverComposite()。addResolvers(resolvers);}初始化returnValueHandlers属性if(this。returnValueHandlersnull){ListHandlerMethodReturnValueHandlerhandlersgetDefaultReturnValueHandlers();this。returnValueHandlersnewHandlerMethodReturnValueHandlerComposite()。addHandlers(handlers);}}4。拦截器的初始化
  因为所有的HandlerMapping预制的策略类都继承了AbstractHandlerMapping,而AbstractHandlerMapping实现了ApplicationContextAware接口,所以在具体的HandlerMapping策略类初始化完之后会调用initApplicationContext方法,该方法中具体实现了拦截器的创建,代码如下:protectedvoidinitApplicationContext()throwsBeansException{空实现,交给子类实现,用于注册自定义的拦截器到interceptors中,目前暂无子类实现extendInterceptors(this。interceptors);扫描已注册的MappedInterceptor的Bean们,添加到adaptedInterceptors中detectMappedInterceptors(this。adaptedInterceptors);将interceptors初始化成HandlerInterceptor类型,添加到adaptedInterceptors中initInterceptors();}三、SpringMVC请求过程1。请求流程图
  2。业务描述
  1。请求进来后会调用FrameworkServlet的service()方法,该方法中会调用(HttpServlet)super。service方法,其中会调用doXXX()方法,而doXXX()方法在FrameworkServlet重写,每个doXXX()方法中又会调用processRequest(request,response)方法,processRequest中会调用doService(),doService()中又会调用doDispatch(),整个业务处理逻辑定义在doDispatch方法中。
  2。循环遍历在启动过程中创建的handlerMapping处理器映射器集合查找对应处理器,传入参数为request请求对象,返回的是HandlerExecutionChain类型的对象,代码如下protectedHandlerExecutionChaingetHandler(HttpServletRequestrequest)throwsException{if(this。handlerMappings!null){遍历for(HandlerMappingmapping:this。handlerMappings){HandlerExecutionChainhandlermapping。getHandler(request);if(handler!null){}}}}
  在getHandler方法中如果找到具体的handler对象(HandlerMethod类型),会继续封装handler对象为一个executionChain处理器链链对象(HandlerExecutionChain类型),代码如下:ObjecthandlergetHandlerInternal(request);if(handlernull){handlergetDefaultHandler();}如果handler为null即返回null。说明当前的处理器映射器不匹配。if(handlernull){}Beannameorresolvedhandler?if(handlerinstanceofString){StringhandlerName(String)handlerobtainApplicationContext()。getBean(handlerName);}EnsurepresenceofcachedlookupPathforinterceptorsandothersif(!ServletRequestPathUtils。hasCachedPath(request)){initLookupPath(request);}创建处理器链HandlerExecutionChainexecutionChaingetHandlerExecutionChain(handler,request);
  getHandlerInternal是多态方法,具体的实现类中有不同的实现方式。查找具体的HandlerMethod逻辑比较复杂,请自行查看源码。
  3。循环遍历在启动过程中创建的handlerAdapters处理器适配器集合查找对应处理器适配器,传入参数为handler处理器对象,返回的是RequestMappingHandlerAdapter类型的处理器适配器,代码如下:protectedHandlerAdaptergetHandlerAdapter(Objecthandler)throwsServletException{if(this。handlerAdapters!null){循环判断哪个适配器能处理传入的处理器for(HandlerAdapteradapter:this。handlerAdapters){if(adapter。supports(handler)){}}}thrownewServletException(Noadapterforhandler〔handler〕:TheDispatcherServletconfigurationneedstoincludeaHandlerAdapterthatsupportsthishandler);}
  4。循环执行mappedHandler(HandlerExecutionChain拦截器链)对象的拦截器preHandle方法。
  5。处理器适配器调用处理方法,最终会执行ServletInvocableHandlerMethod。invokeAndHandle()方法,此方法中会调用invokeForRequest,invokeForRequest中会先拿到Controller中方法的具体参数值,再执行该方法,最后会返回ModelAndView对象。
  6。循环执行mappedHandler(HandlerExecutionChain拦截器链)对象的拦截器postHandle方法。
  7。processDispatchResult方法中会先查找找到具体的视图引擎,代码如下:protectedViewresolveViewName(StringviewName,NullableMapString,Objectmodel,Localelocale,HttpServletRequestrequest)throwsException{if(this。viewResolvers!null){for(ViewResolverviewResolver:this。viewResolvers){ViewviewviewResolver。resolveViewName(viewName,locale);if(view!null){}}}}
  然后渲染视图内容,底层其实就是请求的转发,代码如下:publicvoidrender(NullableMapString,?model,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{if(logger。isDebugEnabled()){logger。debug(ViewformatViewName(),model(model!null?model:Collections。emptyMap())(this。staticAttributes。isEmpty()?:,staticattributesthis。staticAttributes));}合并返回结果,将Model中的静态数据和请求中的动态数据进行合并MapString,ObjectmergedModelcreateMergedOutputModel(model,request,response);prepareResponse(request,response);进行渲染renderMergedOutputModel(mergedModel,getRequestToExpose(request),response);}
  8。循环执行mappedHandler(HandlerExecutionChain拦截器链)对象的拦截器afterCompletion方法。
投诉 评论 转载

理查利森谈孔蒂此前和图赫尔冲突没人敢借此开孔蒂玩笑近日,热刺球员理查利森在接受媒体采访时谈到了此前孔蒂和前切尔西主帅孔蒂在本赛季联赛第二轮赛后的争吵,他表示热刺队中没有一个球员敢拿这件事跟孔蒂开玩笑。理查利森对于这次争吵……VR开发商SchellGames向慈善机构捐赠2万美元在MetaConnect2022大会期间,开发商SchellGames宣布了其《IExpectYouToDie》MR扩展内容以及《AmongUsVR》的官方发布日期。为了……胆固醇超标,饮食要注意哪些?5大禁忌要牢记在心如果有胆固醇指标过高这种情况,说明血液会逐渐粘稠,后续循环受到影响,血压无法及时提供给需要的部位,会引发各种不良症状。有的人心绞痛、容易头晕、肢体发麻,都是因为血液粘稠如……风声鸡娃教育与身份困惑冬奥学霸全才给中国父母带来怎样的焦虑?作者李小笼在本届冬奥会上,出现了很多学霸全才的面孔,他们不仅在体育界大放异彩,还在学业上取得令人欣羡的成绩,甚至还有像苏翊鸣那样的选手,不仅夺得中国男子第一位单板滑雪奖牌……京城老中医张东明脾虚可能是中气不足,补脾调中气乃为关键日常门诊有不少病人会问到:大夫,我平时在饮食方面很注意,本身脾胃就不好,几乎不怎么吃凉的,但是舌苔白而且舌边有齿痕,这说明体内有湿气吗?体内的湿气从哪里来?相信诸如这样的问题,……一个女人有没有见过大世面,看她戴的饰品就知道,和钱多少没关系能够最直接地感受到一个女人是否见过世面,其实只需要从她身上的饰品上入手。真正有眼光、会打扮的女人,又怎么会在饰品上踩雷呢?有品味的女人,能够通过服装、妆发去衬托出饰品的高贵感,……中国人正在丢失的9样东西快节奏的时代,给我们带了巨大的便利,同时也失去了很多的东西;我们拥有快捷的的同时,同样也丢失了某些传统,因为步伐太快,以致于忘了当初为何出发……被吹上天的5类保健品,实则没啥用,劝告父母尽量少买生活水平提高之后,很多人会选择各种各样的保健品,考虑今天吃什么菜,明天买什么水果,实际上健康食品并没有人们想象当中的那么完美无瑕。2015年我国保健品行业市场稳步增长25……SpringMVC请求流程源码分析一、SpringMVC使用1。工程创建创建maven工程。添加java、resources目录。引入Springwebmvc依赖。dependencygroupIdorg。sp……RNG惨遭横扫止步八强!李哥7进S赛保底四强,Wei当场痛哭RNG送大飞回家失败,没想到回家的是自己,而且没想到回家得这么快是个03。从S3的03,到S6的13,和S7的23本以为今年RNG会是突破的32,结果没想到却是轮回……WiFi6全千兆智能组网路由,蒲公英X5远程访问教程公司在用的宽带从100兆升级成为300兆,之前的百兆企业路由就有点扯后腿了,本着资源利用率最大化的原则,一并升级一下现有的网络设备,解决大家一直苦恼的网络信号弱、速度慢的问题,……大侄子这样带辽迷节奏,万一本赛季又拿总亚军,会不会被球迷骂死第二阶段辽粤两队狭路相逢,辽宁大胜而归。于是乎,辽宁球迷和恨广东宏远新三连冠的北京球迷、浙江球迷、东北球迷,这几天跟农村过年杀猪似的,嗨得不行不行了。辽宁大比分赢广东宏远,恨广……
白忙一场!湖人加时惜败绿军,詹姆斯空砍准三双,浓眉又掉链子蔬菜不能随便买,这8种蔬菜打农药多,为了家人健康着想,别买了年底将近,各种酒席少不了,记住千万别带这3种酒,有损颜面明星们的婚姻怎么了,又有两位明星离婚了时间,会留下最真的人风俗街的香艳灵魂和她们未完成的归处阳光心态健康人生女性经期最怕什么?VR技术助力电力职业培训创新实践120W闪充1亿像素三星屏,仅1479元,还要什么iPhon总投资2200亿元12项重大铁路公路机场项目获批(附中标)畅游庄浪精品旅游线路羊毛被怎么清洗被芯脏了能用水洗吗70的帕金森病患者有睡眠障碍,几点教你如何保证睡眠质量我喜欢的季节单方申请离婚孩子才两个月大法院会判男方还是女方?四年级上册语文教学计划雪的天地六年级优秀作文小河变丑的启示作文轴距2米7,颜值酷似雷克萨斯ES,仅售6。5w,一上市销量就月亮升起来时遇龙河游记的作文500字关于七五保密法制宣传教育的实施方案电动车无序充电时代即将结束?夜晚波谷充电习惯或将借经济手段形

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利