org.springframework.web.servlet.DispatcherServlet.doDispatch{
// 根据请求对象获取能处理这个请求的Handler,可能是一个HandlerMethod对象,也可能是一个Handler类,它实现了Controller接口等等
HandlerExecutionChain mappedHandler = getHandler(processedRequest);{
if (this.handlerMappings != null) {
// 遍历我们初始化的HandlerMapping,如果不自定义,默认就是提供了三个
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);{
// 返回Object是因为getHandlerInternal是一个抽象方法
// 处理请求的Handler可能是一个beanName->Bean,也可能是一个实现了Controller接口的对象,等等
Object handler = getHandlerInternal(request);{
String lookupPath = initLookupPath(request);
Object handler = lookupHandler(lookupPath, request);{
Object handler = getDirectMatch(lookupPath, request);{
// 这个就是在BeanNameUrlHandlerMapping保存的映射信息的map,直接从那里面获取
Object handler = this.handlerMap.get(urlPath);
if (handler != null) {
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 校验handler,空实现
validateHandler(handler, request);
return buildPathExposingHandler(handler, urlPath, urlPath, null);{
// 通过handler构建HandlerExecutionChain对象
HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
// 添加一个拦截器,这个拦截器是在请求之前,在request存入一些东西
// exposePathWithinMapping(this.bestMatchingPattern, this.pathWithinMapping, request);
// request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, handler);
// request.setAttribute(INTROSPECT_TYPE_LEVEL_MAPPING, supportsTypeLevelMappings());
chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
// 如果beanName存在路径变量,但是这个方法传递的实null,表明不可以有路径变量
if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
// 还要单独添加一个拦截器来处理
// 设置路径变量到请求域中
// request.setAttribute(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
}
}
}
}
if (handler != null) {
return handler;
}
}
}
// 找了很多资料,没有找到可能成立的情况,可能是兼容老版本的配置,因为上面的Handler都会判断如果为string就从spring容器获取
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 将handler以及拦截器封装成一个HandlerExecutionChain对象
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);{
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
// 如果是MappedInterceptor这种蓝接触器
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
// 判断这个拦截器是否可以作用当前请求
if (mappedInterceptor.matches(request)) {
// 添加进去拦截器
chain.addInterceptor(mappedInterceptor.getInterceptor());
return;
}
}
chain.addInterceptor(interceptor);
}
return chain;
}
// 是否有跨域配置
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = getCorsConfiguration(handler, request);
config.validateAllowCredentials();
// 添加一个跨域拦截器
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);{
chain.addInterceptor(0, new CorsInterceptor(config));
}
}
return executionChain;
}
// 返回handler
if (handler != null) {
return handler;
}
}
}
}
}
BeanNameUrlHandlerMapping运行原理
于 2024-01-20 23:04:45 首次发布
本文详细描述了SpringMVC中DispatcherServlet如何获取并处理请求,包括Handler的查找、HandlerExecutionChain的构建,以及跨域(CORS)配置的过程。
1520

被折叠的 条评论
为什么被折叠?



