Spring5 源码阅读笔记(5.2.2)getHandler
程序员文章站
2022-03-06 08:06:38
...
类 DispatcherServlet
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//handlerMappering实例
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
//获取HandlerMethod和过滤器链的包装类
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
//优先级高的handlerMappering能处理直接返回
return handler;
}
}
}
return null;
}
跟 getHandler:
类 AbstractHandlerMapping
@Override
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//根据请求的uri拿到对应的HandlerMethod对象 见5.2.2.1
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);
}
//获取HandlerMethod和过滤器链的包装类 见5.2.2.2
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());
}
//是否是跨域请求,就是查看request请求头中是否有Origin属性
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;
}
类 AbstractHandlerMethodMapping< T >,它实现了 InitializingBean 接口,意味着肯定重写了 afterPropertiesSet 方法,见 Spring5 源码阅读笔记(5.2.1)AbstractHandlerMapping 里的 afterPropertiesSet。
5.2.2.1 getHandlerInternal
有请求过来之后
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//从request对象中获取uri
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
this.mappingRegistry.acquireReadLock();
try {
//根据uri从映射关系中找到对应的HandlerMethod对象
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
//把Controller类实例化
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
跟 lookupHandlerMethod:
@Nullable
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()) {
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
if (logger.isTraceEnabled()) {
logger.trace(matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
Match secondBestMatch = matches.get(1);
//如果两个RequestMappinginfo什么都相同,报错
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);
}
}
跟 addMatchingMappings:
private void addMatchingMappings(Collection<T> mappings, List<Match> matches, HttpServletRequest request) {
for (T mapping : mappings) {
//T:RequestMappingInfo,如果@RequestMapping和request不匹配就会返回null
T match = getMatchingMapping(mapping, request);
if (match != null) {
//RequestMappingInfo对象和HandlerMethod对象封装到Match对象中
matches.add(new Match(match, this.mappingRegistry.getMappings().get(mapping)));
}
}
}
5.2.2.2 getHandlerExecutionChain
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//把HandlerMethod对象包装到HandlerExecutionChain对象中,这个对象中有一个拦截器数组
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
//获取uri
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;
}
adaptedInterceptors 里的拦截器哪里来的?
Spring5 源码阅读笔记(5)基于注解的方法替换spring-dispatcher.xml 里已经介绍了,interceptors 里面是有值的。那么 adaptedInterceptors 里的值是什么时候放进去的呢?
同样在这个类里,有个初始化上下文方法:
@Override
protected void initApplicationContext() throws BeansException {
extendInterceptors(this.interceptors);
detectMappedInterceptors(this.adaptedInterceptors);
//初始化上下文时,就会调用
initInterceptors();
}
跟 initInterceptors:
protected void initInterceptors() {
if (!this.interceptors.isEmpty()) {
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i);
if (interceptor == null) {
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
}
//对interceptor进行了适配操作
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
跟 adaptInterceptor:
//判断实现了哪个接口
protected HandlerInterceptor adaptInterceptor(Object interceptor) {
if (interceptor instanceof HandlerInterceptor) {
return (HandlerInterceptor) interceptor;
}
else if (interceptor instanceof WebRequestInterceptor) {
return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);
}
else {
throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName());
}
}