SpringMvc 源码分析-查找Mapping
2017-09-09 本文已影响61人
数齐
上一篇我们简单介绍了注册Mapping ,这次我们介绍怎么查找。首先我们知道Spring mvc的核心组件DispatcherServlet,他是一个Servlet,并且所有的请求都要交给他来处理,
我们看一下他的doService,他里面调用了doDispatch来处理请求
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest); //这就是我们这片文章索要讲述的,获取mappinghander
...
}
看一下具体的实现
/**
* Return the HandlerExecutionChain for this request.
* <p>Tries all handler mappings in order.
* @param request current HTTP request
* @return the HandlerExecutionChain, or {@code null} if no handler could be found
*/
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request); // 获取Handler
if (handler != null) {
return handler;
}
}
return null;
}
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request); //获得内部handler
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
/**
* Look up a handler method for the given request.
*/
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); //解析得到请求的URL
if (logger.isDebugEnabled()) {
logger.debug("Looking up handler method for path " + lookupPath);
}
this.mappingRegistry.acquireReadLock();
try {
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
if (logger.isDebugEnabled()) {
if (handlerMethod != null) {
logger.debug("Returning handler method [" + handlerMethod + "]");
}
else {
logger.debug("Did not find handler method for [" + lookupPath + "]");
}
}
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
上一篇我们将找到,所有的MappingHandler,都放进了mappingRegistry,在这里就发挥了用处,根据url找到具体的
HandlerMethod,然后返回,在org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler中封装成HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
然后返回executionChain,给DispatchServlet使用。就是这么查的,比较清爽一点