spring mvc 源码分析
spring mvc 源码分析之处理器和适配器的获取
流程图
一、Handler是什么?
handler在springmvc中代表了控制器,interceptors是拦截器,后面我们通过手写实现spring mvc就能清楚的知道,简单理解其实就是控制类中的某个方法,上面标注了请求路径,与其一一绑定的一个方法来处理请求。
在源码中handler 是一个object类的变量名。用来接收HandlerMethod 类。
HandlerMethod 类中封装了集体需要调用的方法,哪一个控制类 ,方法所需要的参数信息等等。
public class HandlerMethod {
/** Logger that is available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
// 方法所在实现类
private final Object bean;
@Nullable
private final BeanFactory beanFactory;
private final Class<?> beanType;
// 方法对象
private final Method method;
private final Method bridgedMethod;
// 方法所需要的参数
private final MethodParameter[] parameters;
@Nullable
private HttpStatus responseStatus;
@Nullable
private String responseStatusReason;
@Nullable
private HandlerMethod resolvedFromHandlerMethod;
// 方法标注的注解集合
@Nullable
private volatile List<Annotation[][]> interfaceParameterAnnotations;
private final String description;
一、如何通过请求路径找到对应的HandlerExecutionChain
HandlerExecutionChain包含 Handler(控制器)和HandlerInterceptor(拦截器)
DispatcherServlet#doDispatch方法中的getHandler(processedRequest)就是来获取HandlerExecutionChain。
上图的四个handlerMapping是在初始化时就生成好的。
AbstractHandlerMapping#getHandler(HttpServletRequest request)获取处理器
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 将处理器和拦截器封装成HandlerExecutionChain对象返回
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());
}
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
AbstractHandlerMethodMapping#getHandlerInternal(HttpServletRequest request)
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 获取当前请求的请求路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
// 获取读锁
this.mappingRegistry.acquireReadLock();
try {
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
// 解锁
this.mappingRegistry.releaseReadLock();
}
}
lookupHandlerMethod(lookupPath, request) 获取到HandlerMethod
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
// 里面存放路径和处理方法的映射
List<Match> matches = new ArrayList<>();
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
// 循环去查找并放入匹配集合中
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
// No choice but to go through all mappings...
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
}
if (!matches.isEmpty()) {
Match bestMatch = matches.get(0);
// 找出两个处理器 会判断请求方式
if (matches.size() > 1) {
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
bestMatch = matches.get(0);
if (logger.isTraceEnabled()) {
logger.trace(matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
}
else {
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}
一、HandlerAdapter
源码分析
一、HandlerAdapter调用handler处理之前
如果有拦截器会先调用拦截器的preHandle方法,返回true才能继续执行。
DispatcherServlet#mappedHandler.applyPreHandle(processedRequest, response)
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 获取配置的拦截器数组
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
// 执行拦截器的preHandle方法 如果该方法返回false就不会进入handler进行数据处理
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}