SpringMVC源码解读之HandlerMapping - AbstractUrlHandlerMapping系列request分发
AbstractHandlerMapping实现HandlerMapping接口定的getHandler
1.提供getHandlerInternal模板方法给子类实现
2.如果没有获取Handler,则使用默认的defaultHandler
3.如果handler是string类型,从context获取实例
4.通过getHandlerExecutionChain封装handler,添加interceptor
//AbstractHandlerMapping /** *Lookupahandlerforthegivenrequest,fallingbacktothedefault *handlerifnospecificoneisfound. *@paramrequestcurrentHTTPrequest *@returnthecorrespondinghandlerinstance,orthedefaulthandler *@see#getHandlerInternal */ publicfinalHandlerExecutionChaingetHandler(HttpServletRequestrequest)throwsException{ Objecthandler=getHandlerInternal(request); if(handler==null){ handler=getDefaultHandler(); } if(handler==null){ returnnull; } //Beannameorresolvedhandler? if(handlerinstanceofString){ StringhandlerName=(String)handler; handler=getApplicationContext().getBean(handlerName); } returngetHandlerExecutionChain(handler,request); } //AbstractHandlerMapping /** *BuildaHandlerExecutionChainforthegivenhandler,includingapplicableinterceptors. *<p>ThedefaultimplementationsimplybuildsastandardHandlerExecutionChainwith *thegivenhandler,thehandlermapping'scommoninterceptors,andany{@linkMappedInterceptor}s *matchingtothecurrentrequestURL.Subclassesmay *overridethisinordertoextend/rearrangethelistofinterceptors. *<p><b>NOTE:</b>Thepassed-inhandlerobjectmaybearawhandlerorapre-built *HandlerExecutionChain.Thismethodshouldhandlethosetwocasesexplicitly, *eitherbuildinganewHandlerExecutionChainorextendingtheexistingchain. *<p>Forsimplyaddinganinterceptor,considercalling{@codesuper.getHandlerExecutionChain} *andinvoking{@linkHandlerExecutionChain#addInterceptor}onthereturnedchainobject. *@paramhandlertheresolvedhandlerinstance(never{@codenull}) *@paramrequestcurrentHTTPrequest *@returntheHandlerExecutionChain(never{@codenull}) *@see#getAdaptedInterceptors() */ protectedHandlerExecutionChaingetHandlerExecutionChain(Objecthandler,HttpServletRequestrequest){ HandlerExecutionChainchain= (handlerinstanceofHandlerExecutionChain)? (HandlerExecutionChain)handler:newHandlerExecutionChain(handler); chain.addInterceptors(getAdaptedInterceptors()); StringlookupPath=urlPathHelper.getLookupPathForRequest(request); for(MappedInterceptormappedInterceptor:mappedInterceptors){ if(mappedInterceptor.matches(lookupPath,pathMatcher)){ chain.addInterceptor(mappedInterceptor.getInterceptor()); } } returnchain; }
接下来看看AbstractUrlHandlerMapping实现的getHandlerInternal
//AbstractUrlHandlerMapping /** *LookupahandlerfortheURLpathofthegivenrequest. *@paramrequestcurrentHTTPrequest *@returnthehandlerinstance,or{@codenull}ifnonefound */ @Override protectedObjectgetHandlerInternal(HttpServletRequestrequest)throwsException{ //根据request获取url StringlookupPath=getUrlPathHelper().getLookupPathForRequest(request); //根据url查找handler Objecthandler=lookupHandler(lookupPath,request); if(handler==null){ //如果没有匹配到handler需要查找默认的,下面需要将PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE缓存到request //Weneedtocareforthedefaulthandlerdirectly,sinceweneedto //exposethePATH_WITHIN_HANDLER_MAPPING_ATTRIBUTEforitaswell. ObjectrawHandler=null; if("/".equals(lookupPath)){ rawHandler=getRootHandler(); } if(rawHandler==null){ rawHandler=getDefaultHandler(); } if(rawHandler!=null){ //Beannameorresolvedhandler? if(rawHandlerinstanceofString){ StringhandlerName=(String)rawHandler; rawHandler=getApplicationContext().getBean(handlerName); } //预留的校验handler模板方法,没有使用 validateHandler(rawHandler,request); //添加expose属性到request的拦截器 handler=buildPathExposingHandler(rawHandler,lookupPath,lookupPath,null); } } if(handler!=null&&logger.isDebugEnabled()){ logger.debug("Mapping["+lookupPath+"]to"+handler); } elseif(handler==null&&logger.isTraceEnabled()){ logger.trace("Nohandlermappingfoundfor["+lookupPath+"]"); } returnhandler; } //AbstractUrlHandlerMapping /** *LookupahandlerinstanceforthegivenURLpath. *<p>Supportsdirectmatches,e.g.aregistered"/test"matches"/test", *andvariousAnt-stylepatternmatches,e.g.aregistered"/t*"matches *both"/test"and"/team".Fordetails,seetheAntPathMatcherclass. *<p>Looksforthemostexactpattern,wheremostexactisdefinedas *thelongestpathpattern. *@paramurlPathURLthebeanismappedto *@paramrequestcurrentHTTPrequest(toexposethepathwithinthemappingto) *@returntheassociatedhandlerinstance,or{@codenull}ifnotfound *@see#exposePathWithinMapping *@seeorg.springframework.util.AntPathMatcher */ protectedObjectlookupHandler(StringurlPath,HttpServletRequestrequest)throwsException{ //Directmatch?直接根据url进行查找handler Objecthandler=this.handlerMap.get(urlPath); if(handler!=null){ //Beannameorresolvedhandler? if(handlerinstanceofString){ StringhandlerName=(String)handler; handler=getApplicationContext().getBean(handlerName); } validateHandler(handler,request); returnbuildPathExposingHandler(handler,urlPath,urlPath,null); } //Patternmatch?通过表达式进行匹配具体通过AntPathMatcher实现,具体后面分析 List<String>matchingPatterns=newArrayList<String>(); for(StringregisteredPattern:this.handlerMap.keySet()){ if(getPathMatcher().match(registeredPattern,urlPath)){ matchingPatterns.add(registeredPattern); } } StringbestPatternMatch=null; Comparator<String>patternComparator=getPathMatcher().getPatternComparator(urlPath); if(!matchingPatterns.isEmpty()){ Collections.sort(matchingPatterns,patternComparator); if(logger.isDebugEnabled()){ logger.debug("Matchingpatternsforrequest["+urlPath+"]are"+matchingPatterns); } //order序号最小的优先级最高 bestPatternMatch=matchingPatterns.get(); } if(bestPatternMatch!=null){ handler=this.handlerMap.get(bestPatternMatch); //Beannameorresolvedhandler? if(handlerinstanceofString){ StringhandlerName=(String)handler; handler=getApplicationContext().getBean(handlerName); } validateHandler(handler,request); StringpathWithinMapping=getPathMatcher().extractPathWithinPattern(bestPatternMatch,urlPath); //Theremightbemultiple'bestpatterns',let'smakesurewehavethecorrectURItemplatevariables //forallofthem Map<String,String>uriTemplateVariables=newLinkedHashMap<String,String>(); for(StringmatchingPattern:matchingPatterns){ if(patternComparator.compare(bestPatternMatch,matchingPattern)==){ Map<String,String>vars=getPathMatcher().extractUriTemplateVariables(matchingPattern,urlPath); Map<String,String>decodedVars=getUrlPathHelper().decodePathVariables(request,vars); uriTemplateVariables.putAll(decodedVars); } } if(logger.isDebugEnabled()){ logger.debug("URITemplatevariablesforrequest["+urlPath+"]are"+uriTemplateVariables); } returnbuildPathExposingHandler(handler,bestPatternMatch,pathWithinMapping,uriTemplateVariables); } //Nohandlerfound... returnnull; }
设计用于校验Handler,实际什么都没做,包括子类.
/** *Validatethegivenhandleragainstthecurrentrequest. *<p>Thedefaultimplementationisempty.Canbeoverriddeninsubclasses, *forexampletoenforcespecificpreconditionsexpressedinURLmappings. *@paramhandlerthehandlerobjecttovalidate *@paramrequestcurrentHTTPrequest *@throwsExceptionifvalidationfailed */ protectedvoidvalidateHandler(Objecthandler,HttpServletRequestrequest)throwsException{ }
封装handler为HandlerExecutionChain,并添加PathExposingHandlerInterceptor和UriTemplateVariablesHandlerInterceptor拦截器.
/** *Buildahandlerobjectforthegivenrawhandler,exposingtheactual *handler,the{@link#PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE},aswellas *the{@link#URI_TEMPLATE_VARIABLES_ATTRIBUTE}beforeexecutingthehandler. *<p>Thedefaultimplementationbuildsa{@linkHandlerExecutionChain} *withaspecialinterceptorthatexposesthepathattributeanduritemplatevariables *@paramrawHandlertherawhandlertoexpose *@parampathWithinMappingthepathtoexposebeforeexecutingthehandler *@paramuriTemplateVariablestheURItemplatevariables,canbe{@codenull}ifnovariablesfound *@returnthefinalhandlerobject */ protectedObjectbuildPathExposingHandler(ObjectrawHandler,StringbestMatchingPattern, StringpathWithinMapping,Map<String,String>uriTemplateVariables){ HandlerExecutionChainchain=newHandlerExecutionChain(rawHandler); chain.addInterceptor(newPathExposingHandlerInterceptor(bestMatchingPattern,pathWithinMapping)); if(!CollectionUtils.isEmpty(uriTemplateVariables)){ chain.addInterceptor(newUriTemplateVariablesHandlerInterceptor(uriTemplateVariables)); } returnchain; }
以上内容是小编给大家介绍的SpringMVC源码解读之HandlerMapping-AbstractUrlHandlerMapping系列request分发的相关知识,希望对大家有所帮助!