AbstractUrlHandlerMapping类功能简介说明
下文笔者将讲述AbstractUrlHandlerMapping类的相关简介说明,如下所示:
这里我们看到了之前说的Map对象,用来存储url和Handler之间的关系,
当Handler获取为String时需要从Bean容器中获取注入的实现类,
当然在查找过程中也会有模糊匹配等查找过程。
AbstractUrlHandlerMapping是AbstractHandlerMapping的子类 AbstractUrlHandlerMapping的功能:将beanName注册为handler对象。
registerHandler() 注册handler对象
//注册url和Bean的map,注册多个string的url到一个处理器中
protected void registerHandler(String[] urlPaths, String beanName) throws BeansException, IllegalStateException {
Assert.notNull(urlPaths, "URL path array must not be null");
//最终调用另外一个重载方法
for (String urlPath : urlPaths) {
registerHandler(urlPath, beanName);
}
}
////注册url和Bean的map,将具体的Handler注入到url对应的map中
protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
//两参数不可为空
Assert.notNull(urlPath, "URL path must not be null");
Assert.notNull(handler, "Handler object must not be null");
Object resolvedHandler = handler;
// Eagerly resolve handler if referencing singleton via name.
//如果Handler是String类型而且没有设置lazyInitHandlers则从springMVC容器中获取handler
if (!this.lazyInitHandlers && handler instanceof String) {
String handlerName = (String) handler;
if (getApplicationContext().isSingleton(handlerName)) {
resolvedHandler = getApplicationContext().getBean(handlerName);
}
}
//是否已存在对应的handler
Object mappedHandler = this.handlerMap.get(urlPath);
if (mappedHandler != null) {
if (mappedHandler != resolvedHandler) {
throw new IllegalStateException(
"Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
"]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
}
}
else {
//未存在
if (urlPath.equals("/")) {
if (logger.isInfoEnabled()) {
logger.info("Root mapping to " + getHandlerDescription(handler));
}
//"/"-->设置为roothandler
setRootHandler(resolvedHandler);
else if (urlPath.equals("/*")) {
if (logger.isInfoEnabled()) {
logger.info("Default mapping to " + getHandlerDescription(handler));
}
//对"/*"的匹配设置默认的handler
setDefaultHandler(resolvedHandler);
}
else {
//其余的路径绑定关系则存入handlerMap
this.handlerMap.put(urlPath, resolvedHandler);
if (logger.isInfoEnabled()) {
logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
}
}
}
}
getHandlerInternal() 获取Handler
@Override
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
// 根据request获取url
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
// 根据url查找handler
Object handler = lookupHandler(lookupPath, request);
if (handler == null) {
// 如果没有匹配到handler需要查找默认的,下面需要将PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE缓存到request
// We need to care for the default handler directly, since we need to
// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
// Bean name or resolved handler?
if (rawHandler instanceof String) {
String handlerName = (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);
}
else if (handler == null && logger.isTraceEnabled()) {
logger.trace("No handler mapping found for [" + lookupPath + "]");
}
return handler;
}
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
// Direct match? 直接根据url进行查找handler
Object handler = this.handlerMap.get(urlPath);
if (handler != null) {
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
return buildPathExposingHandler(handler, urlPath, urlPath, null);
}
// Pattern match? 通过表达式进行匹配具体通过AntPathMatcher实现,具体后面分析
listmatchingPatterns = new ArrayList();
for (String registeredPattern : this.handlerMap.keySet()) {
if (getPathMatcher().match(registeredPattern, urlPath)) {
matchingPatterns.add(registeredPattern);
}
}
String bestPatternMatch = null;
//匹配规则
ComparatorpatternComparator = getPathMatcher().getPatternComparator(urlPath);
if (!matchingPatterns.isEmpty()) {
Collections.sort(matchingPatterns, patternComparator);
if (logger.isDebugEnabled()) {
logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
}
// order序号最小的优先级最高
bestPatternMatch = matchingPatterns.get(0);
}
if (bestPatternMatch != null) {
handler = this.handlerMap.get(bestPatternMatch);
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);
// There might be multiple 'best patterns', let's make sure we have the correct URI template variables
// for all of them
Map uriTemplateVariables = new LinkedHashMap();
for (String matchingPattern : matchingPatterns) {
if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {
Map vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
Map decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
uriTemplateVariables.putAll(decodedVars);
}
}
if (logger.isDebugEnabled()) {
logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
}
return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
}
// No handler found...
return null;
}
//用于给找到的Handler注册两个拦截器PathExposingHandlerInterceptor和UriTemplateVariablesHandlerInterceptor
//这两个拦截器的的作用是将与当前url实际匹配的Pattern、匹配条件和url模板参数设置到request的属性中
protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,
String pathWithinMapping, Map uriTemplateVariables) {
HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
}
return chain;
}
getHandlerInternal首先是通过lookupHandler方法来查找Handler,这里我们看到了之前说的Map对象,用来存储url和Handler之间的关系,
当Handler获取为String时需要从Bean容器中获取注入的实现类,
当然在查找过程中也会有模糊匹配等查找过程。
通过以上分析,我们可以得知:
AbstractUrlHandlerMapping的功能:
将请求路径绑定beanName
它提供的功能是根据url从handlerMap中获取handler和注册url和handler的对应关系到handlerMap中
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


