Handler映射器为请求生成对应的Handler执行链
Handler映射器在DispatcherServlet中
- 作为成员变量被调用
@Nullable
private List<HandlerMapping> handlerMappings;
-
initHandlerMappings方法中被初始化(作为HttpServlet被初始化时会间接调用到此方法)
private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { // 获取应用上下文所有的Handler映射器 Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList<>(matchingBeans.values()); // 对Handler映射器排序 AnnotationAwareOrderComparator.sort(this.handlerMappings); } }else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); this.handlerMappings = Collections.singletonList(hm); }catch (NoSuchBeanDefinitionException ex) { } } // 上下文没有就加一个默认的Handler映射器并记录日志 if (this.handlerMappings == null) { this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isTraceEnabled()) { logger.trace("No HandlerMappings declared for servlet '" + getServletName() + "': using default strategies from DispatcherServlet.properties"); } } }
doDispatch方法中负责获取Handler执行链
//获取请求对应的handler执行链
mappedHandler = getHandler(processedRequest);
查看DispatcherServlet的getHandler方法(怎么根据请求获取Handler执行链)
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
//遍历所有Handler映射器,直到有映射器可以获取到请求对应的Handler执行链
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
看来执行链的获取最终由某一个HandlerMapping的getHandler方法实现,那就要通过查看HandlerMapping接口以进一步了解
查看HandlerMapping接口
public interface HandlerMapping {
//一堆字符串成员变量
String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";
String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
/**获取Handler执行链
* Return a handler and any interceptors for this request. The choice may be made
* on request URL, session state, or any factor the implementing class chooses.
**/
@Nullable
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
可以看到HandlerMapping接口只有一个方法——getHandler用于获取请求对应的Handler执行链
HandlerMapping部分继承关系
查看子类AbstractHandlerMapping的getHandler方法(查看获取请求对应的Handler执行链的初步抽象实现)
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//首先从请求中获取Handler对应信息
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// 如果Handler信息是string型——进行映射获取对应Handler
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
//根据Handler和请求生成Handler执行链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
//记录日志
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
logger.debug("Mapped to " + executionChain.getHandler());
}
//如果是跨域请求,进行跨域配置
//CORS即Cross Origin Resource Sharing(跨来源资源共享)
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigurationSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}