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分发的相关知识,希望对大家有所帮助!