SpringMVC请求执行流程的源码
1、SpringMVC的工作流程说明:
1.用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet(中央处理器)捕获;
2.DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回给DispatcherServlet(中央处理器);
3.DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
4.提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息数据转换:对请求消息进行数据转换。如String转换成Integer、Double等数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中.
5.Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
6.根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
7.ViewResolver 结合Model和View,来渲染视图
8.将渲染结果返回给客户端。
2、请求执行主线流程的分析
HttpServlet#service //HttpServlet顶层调用
FrameworkServlet#service //子类业务接口处理
FrameworkServlet#processRequest
DispatcherServlet#doService //交给了DispatcherServlet
DispatcherServlet#doDispatch
RequestMappingHandlerAdapter#handleInternal //交给了RequestMappingHandlerAdapter
RequestMappingHandlerAdapter#invokeHandlerMethod //由RequestMappingHandlerAdapter处理
ServletInvocableHandlerMethod#invokeAndHandle
InvocableHandlerMethod#invokeForRequest //交给代理的Controller实现
InvocableHandlerMethod#doInvoke
java.lang.reflect.Method#invoke //底层交给java返回执行
一、DispatcherServlet类的概述
1、DispatcherServlet的继承关系
DispatcherServlet extends FrameworkServlet
FrameworkServlet extends HttpServletBean implements ApplicationContextAware
HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware
HttpServlet extends GenericServlet
GenericServlet implements Servlet, ServletConfig, Serializable
2、DispatcherServlet的关键方法梳理
// 初始化组件构造
DispatcherServlet#initStrategies // 初始化方法
DispatcherServlet#initMultipartResolver // 多文本解析
DispatcherServlet#initLocaleResolver //本地解析
DispatcherServlet#initThemeResolver //主题解析
DispatcherServlet#initHandlerMappings //映射处理器
DispatcherServlet#initHandlerAdapters //适配器
DispatcherServlet#initHandlerExceptionResolvers //异常解析
DispatcherServlet#initRequestToViewNameTranslator //视图转换器
DispatcherServlet#initViewResolvers //视图解析器
DispatcherServlet#initFlashMapManager //flash管理器
//服务方法处理
DispatcherServlet#doService // 运行服务
DispatcherServlet#doDispatch //执行转发
DispatcherServlet#processDispatchResult //执行处理结果
3、FrameworkServlet的关键方法梳理
//初始化方法
FrameworkServlet#initServletBean
FrameworkServlet#initWebApplicationContext
FrameworkServlet#createWebApplicationContext
//各种前端请求
FrameworkServlet#doGet
FrameworkServlet#doPost
FrameworkServlet#doPut
FrameworkServlet#doDelete
FrameworkServlet#doOptions
FrameworkServlet#doTrace
//转发给processRequest
FrameworkServlet#processRequest
4、HttpServletBean和HttpServlet方法梳理
org.springframework.web.servlet.HttpServletBean#init
HttpServlet#service
二、请求处理流程
1、HttpServlet#service
// 实现了DeafultServlet的service方法
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
//构建请求和响应对象
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
//执行service方法
service(request, response);
}
// 将同一请求入口根据method转成对应的请求类型
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获取req的请求方法
String method = req.getMethod();
//判断上次的请求是否修改,如果没有,则直接返回
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
doGet(req, resp);
} else {
long ifModifiedSince;
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
//其他的一些方法处理
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
//以doPost举例,即如果没有子类实现,即返回不支持post方法
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
2、FrameworkServlet以doPost为例
// SpringMvc的FrameworkServlet实现了HttpServlet中的各种方法
@Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//交给processRequest实现
processRequest(request, response);
}
// 同样是交给processRequest方法实现,本质上反映了Web内部处理GET和POST是没有区别
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
// 真正执行处理请求,这是一个模板方法
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
//初始化本地上下文,LocaleContext的实现类SimpleLocaleContext内部保存一个Locale对象,作为本地化
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = buildLocaleContext(request);
//初始化请求的属性内容
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
//web的异步请求管理器,这个会有具体的专题
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
//初始化上下文容器
initContextHolders(request, localeContext, requestAttributes);
Throwable failureCause = null;
try {
//调用doService,交给子类实现
doService(request, response);
} catch (ServletException | IOException ex) {
failureCause = ex;
throw ex;
}finally {
//请求完成后重置上下文
resetContextHolders(request, previousLocaleContext, previousAttributes);
if (requestAttributes != null) {
requestAttributes.requestCompleted();
}
//处理结果日志
logResult(request, response, failureCause, asyncManager);
//发布请求处理事件
publishRequestHandledEvent(request, response, startTime, failureCause);
}
}
//发布请求处理事件
private void publishRequestHandledEvent(HttpServletRequest request, HttpServletResponse response,
long startTime, @Nullable Throwable failureCause) {
if (this.publishEvents && this.webApplicationContext != null) {
// Whether or not we succeeded, publish an event.
long processingTime = System.currentTimeMillis() - startTime;
this.webApplicationContext.publishEvent(
new ServletRequestHandledEvent(this,
request.getRequestURI(), request.getRemoteAddr(),
request.getMethod(), getServletConfig().getServletName(),
WebUtils.getSessionId(request), getUsernameForRequest(request),
processingTime, failureCause, response.getStatus()));
}
}
3、DispatcherServlet#doService 分析探索
- 请求首先经过处理器适配器,找到对应的控制类对应的方法
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
logRequest(request);
//将请求对象的属性注入到Map容器中
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap<>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
//设置属性,应用上下文
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
//本地解析器
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
//本机主题解析器
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
//本机主机资源
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
//flash管理器
if (this.flashMapManager != null) {
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
}
try {
//核心,交给doDispatch执行
doDispatch(request, response);
} finally {
//如果不是异步管理,则清空Map集合资源
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
//执行请求分发处理
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
//异步管理器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//检查是否文件请求
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 获取映射处理器
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 处理适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Get和Head方法另外处理
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//前置检查映射处理器
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 经过处理获取ModelAndView对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//如果是异步管理器启动,则返回,由系统异步处理
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//处理视图名称
applyDefaultViewName(processedRequest, mv);
//映射处理器后置处理
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception ex) {
dispatchException = ex;
} catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//最后处理分发结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
} finally {
//资源清理
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
//获取映射处理器链,这里映射处理器链可以自己扩展,详细建SpringMVC组件的源码专题
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
// 处理器适配器,详细建SpringMVC组件的源码专题
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet “
+”configuration needs to include a HandlerAdapter that supports this handler");
}
//
二、DispatcherServlet的相关初始化
主要初始化各种默认的解析器,处理器,映射器和用户自定义的映射器等
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
//初始化文件处理解析器
initMultipartResolver(context);
//初始化本地化解析器
initLocaleResolver(context);
//初始化主题解析器
initThemeResolver(context);
//初始化处理器映射器
initHandlerMappings(context);
//初始化处理器适配器
initHandlerAdapters(context);
//初始化异常处理器
initHandlerExceptionResolvers(context);
//初始化请求的视图转换器
initRequestToViewNameTranslator(context);
//初始化视图解析器
initViewResolvers(context);
//初始化flash地图管理器
initFlashMapManager(context);
}
三、SpringMVC组件—HandlerMapping 处理器映射器
HandlerMapping的作用是根据请求的URL路径–Controller方法—返回的ModelAndView进行绑定
1、HandlerMapping的getHandler方法跟踪追溯
(1)、HandlerMapping 接口的实现类AbstractHandlerMapping
- 这里留下了一个HandlerInterceptor的内容,后面会继续分析
// 包含的属性
// 默认的处理器
private Object defaultHandler;
// Url匹配工具类
private UrlPathHelper urlPathHelper = new UrlPathHelper();
//URL路径匹配检查
private PathMatcher pathMatcher = new AntPathMatcher();
// 各种拦截器
private final List<Object> interceptors = new ArrayList<>();
//HandlerInterceptor拦截器
private final List<HandlerInterceptor> adaptedInterceptors = new ArrayList<>();
//跨域的解决
private CorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
private CorsProcessor corsProcessor = new DefaultCorsProcessor();
private int order = Ordered.LOWEST_PRECEDENCE; // default: same as non-Ordered
@Nullable
private String beanName;
// 通过请求HttpServletRequest 获取HandlerExecutionChain处理器执行链
@Override
@Nullable
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) {
//如果是通过名称获取的,则通过ApplicationContext获取
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
//获取执行器处理链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
//cors跨域处理
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;
}
//获取处理器执行链 AbstractHandlerMapping#getHandlerExecutionChain
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
//遍历适配的adaptedInterceptors,并将HandlerInterceptor置入到chain中
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;
}
//如果涉及到跨域的,另外添加跨域的处理器
protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
HandlerExecutionChain chain, @Nullable CorsConfiguration config) {
if (CorsUtils.isPreFlightRequest(request)) {
HandlerInterceptor[] interceptors = chain.getInterceptors();
chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
}
else {
chain.addInterceptor(new CorsInterceptor(config));
}
return chain;
}
HandlerExecutionChain 处理器执行器链条
主要用于插入自定义的拦截处理器,类似于AOP做请求前处理以及处理完成后处理
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
private final Object handler;
@Nullable
private HandlerInterceptor[] interceptors;
@Nullable
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex = -1;
}
//前置拦截处理
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];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
//后置拦截处理
void applyPostHandle(HttpServletRequest request, HttpServletResponse response,
@Nullable ModelAndView mv)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
//触发完成后拦截
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
}
catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
//当前处理开始
void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
if (interceptors[i] instanceof AsyncHandlerInterceptor) {
try {
AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i];
asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler);
}
catch (Throwable ex) {
logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex);
}
}
}
}
}
(2)抽象类AbstractHandlerMethodMapping–AbstractHandlerMapping子类
- 主要作用是映射了URL和对应的处理方法
//实现了通过HttpServletRequest中的url获取对应的处理方法
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//获取request的url
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
//加锁
this.mappingRegistry.acquireReadLock();
try {
//通过url获取处理方法
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
//返回处理方法
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}finally {
//释放锁
this.mappingRegistry.releaseReadLock();
}
}
// 通过请求URl获取对应的处理方法
@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) {
//如果没有找到,则将当前url加入到映射注册器
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
// 如果匹配的没有找到,当前URl加入到映射注册器
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);
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 + "}");
}
}
//即将对找到的handlerMethod作为属性设置给请求
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
//将请求,映射和URL做一次匹配处理
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
} else {
//如果没有找到匹配器,则通过this.mappingRegistry.getMappings().keySet()再递归一次,直到找到
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}
//将映射处理器和URL绑定到请求的属性上
protected void handleMatch(T mapping, String lookupPath, HttpServletRequest request) {
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath);
}
// 将从映射注册器找到的映射器,添加到匹配器容器中
private void addMatchingMappings(Collection<T> mappings, List<Match> matches, HttpServletRequest request) {
for (T mapping : mappings) {
T match = getMatchingMapping(mapping, request);
if (match != null) {
matches.add(new Match(match, this.mappingRegistry.getMappings().get(mapping)));
}
}
}
内部类:AbstractHandlerMethodMapping#MappingRegistry
//控制类和映射注册器映射
private final Map<T, MappingRegistration<T>> registry = new HashMap<>();
//控制类和处理方法映射
private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<>();
//URL和控制类映射
private final MultiValueMap<String, T> urlLookup = new LinkedMultiValueMap<>();
//URL对应的处理方法
private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap<>();
//跨域解决映射
private final Map<HandlerMethod, CorsConfiguration> corsLookup = new ConcurrentHashMap<>();
// 读写锁
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//注册映射处理器
public void register(T mapping, Object handler, Method method) {
//加锁
this.readWriteLock.writeLock().lock();
try {
//创建HandlerMethod
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
//检查唯一性
assertUniqueMethodMapping(handlerMethod, mapping);
//将映射缓存起来
this.mappingLookup.put(mapping, handlerMethod);
//获取mapping中的Url,将Url添加到URlMapping映射中
List<String> directUrls = getDirectUrls(mapping);
for (String url : directUrls) {
this.urlLookup.add(url, mapping);
}
//根据命名策略,对Mapping映射命名
String name = null;
if (getNamingStrategy() != null) {
name = getNamingStrategy().getName(handlerMethod, mapping);
addMappingName(name, handlerMethod);
}
// 跨域配置处理
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
this.corsLookup.put(handlerMethod, corsConfig);
}
//将映射器和映射注册器缓存起来
this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
} finally {
//释放锁
this.readWriteLock.writeLock().unlock();
}
}
//从映射器中获取匹配的URl
private List<String> getDirectUrls(T mapping) {
List<String> urls = new ArrayList<>(1);
for (String path : getMappingPathPatterns(mapping)) {
if (!getPathMatcher().isPattern(path)) {
urls.add(path);
}
}
return urls;
}
//内部类 MappingRegistration 映射注册器结构
private static class MappingRegistration<T> {
//映射类
private final T mapping;
//映射方法
private final HandlerMethod handlerMethod;
//对应的url
private final List<String> directUrls;
}
(3)RequestMappingHandlerMapping-- AbstractHandlerMethodMapping的子类
(1)抽象类的RequestMappingHandlerMapping
// 配对处理器 ,根据RequestMappingInfo和lookupPath检查配对
@Override
protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
//设置为url路径配对
super.handleMatch(info, lookupPath, request);
String bestPattern;
Map<String, String> uriVariables;
Set<String> patterns = info.getPatternsCondition().getPatterns();
if (patterns.isEmpty()) {
bestPattern = lookupPath;
uriVariables = Collections.emptyMap();
} else {
bestPattern = patterns.iterator().next();
uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath);
}
// 属性配对
request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern);
if (isMatrixVariableContentAvailable()) {
Map<String, MultiValueMap<String, String>> matrixVars = extractMatrixVariables(request, uriVariables);
request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, matrixVars);
}
Map<String, String> decodedUriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables);
if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) {
Set<MediaType> mediaTypes = info.getProducesCondition().getProducibleMediaTypes();
request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes);
}
}
// 处理不配对的异常处理
@Override
protected HandlerMethod handleNoMatch(
Set<RequestMappingInfo> infos, String lookupPath, HttpServletRequest request) throws ServletException {
PartialMatchHelper helper = new PartialMatchHelper(infos, request);
if (helper.isEmpty()) {
return null;
}
// 如果有方法没有匹配到,则抛异常
if (helper.hasMethodsMismatch()) {
Set<String> methods = helper.getAllowedMethods();
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
HttpOptionsHandler handler = new HttpOptionsHandler(methods);
return new HandlerMethod(handler, HTTP_OPTIONS_HANDLE_METHOD);
}
throw new HttpRequestMethodNotSupportedException(request.getMethod(), methods);
}
// ... ... 省略MIME的生产和消费处理
//如果参数没有匹配上,则抛异常
if (helper.hasParamsMismatch()) {
List<String[]> conditions = helper.getParamConditions();
throw new UnsatisfiedServletRequestParameterException(conditions, request.getParameterMap());
}
return null;
}
(2)实现类的RequestMappingHandlerMapping
//默认匹配后缀
private boolean useSuffixPatternMatch = true;
//默认不注册后缀匹配
private boolean useRegisteredSuffixPatternMatch = false;
private boolean useTrailingSlashMatch = true;
//路径处理
private Map<String, Predicate<Class<?>>> pathPrefixes = new LinkedHashMap<>();
//上下文处理管理器
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
//StringValue的解析器
@Nullable
private StringValueResolver embeddedValueResolver;
//构建配置类
private RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();
//经过扫描判断该类是否是控制类,即包含Controller和RequestMapping注解的类和方法
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
//通过方法名,获取对应的请求映射器
@Override
@Nullable
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
//首先根据method获取RequestMappingInfo
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
//如果没有获取到,则通过handlerType获取
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
if (typeInfo != null) {
info = typeInfo.combine(info);
}
String prefix = getPathPrefix(handlerType);
if (prefix != null) {
//添加前缀内容
info = RequestMappingInfo.paths(prefix).build().combine(info);
}
}
return info;
}
//获取方法的前缀prefix
@Nullable
String getPathPrefix(Class<?> handlerType) {
for (Map.Entry<String, Predicate<Class<?>>> entry : this.pathPrefixes.entrySet()) {
if (entry.getValue().test(handlerType)) {
String prefix = entry.getKey();
if (this.embeddedValueResolver != null) {
prefix = this.embeddedValueResolver.resolveStringValue(prefix);
}
return prefix;
}
}
return null;
}
//创建请求映射信息,这里通过RequestMapping注解获取请求映射
//注意后面的GetMapping,PostMapping等注解都是继承自RequestMapping
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
//根据
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
//
RequestCondition<?> condition = (element instanceof Class ?
getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
//如果没有找到,则再照一次
return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
// 通过扫描RequestMapping创建RequestMappingInfo对象
protected RequestMappingInfo createRequestMappingInfo(
RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {
RequestMappingInfo.Builder builder = RequestMappingInfo
.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
.methods(requestMapping.method())
.params(requestMapping.params())
.headers(requestMapping.headers())
.consumes(requestMapping.consumes())
.produces(requestMapping.produces())
.mappingName(requestMapping.name());
if (customCondition != null) {
builder.customCondition(customCondition);
}
return builder.options(this.config).build();
}
// 通过request和正则匹配,找到对应的RequestMatchResult
@Override
public RequestMatchResult match(HttpServletRequest request, String pattern) {
RequestMappingInfo info = RequestMappingInfo.paths(pattern).options(this.config).build();
//
RequestMappingInfo matchingInfo = info.getMatchingCondition(request);
if (matchingInfo == null) {
return null;
}
Set<String> patterns = matchingInfo.getPatternsCondition().getPatterns();
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
return new RequestMatchResult(patterns.iterator().next(), lookupPath, getPathMatcher());
}
(1)RequestMappingInfo实体类
请求映射类,会将请求参数,请求头,请求方法,请求表达式等通过不同的类进行组装
// 该类是@Controller注解下@RequestMapping注解的方法经过解构后生成的请求映射信息对象
public final class RequestMappingInfo implements RequestCondition<RequestMappingInfo> {
@Nullable
private final String name;
// Url匹配
private final PatternsRequestCondition patternsCondition;
//请求method匹配
private final RequestMethodsRequestCondition methodsCondition;
//请求参数的匹配
private final ParamsRequestCondition paramsCondition;
//请求头匹配
private final HeadersRequestCondition headersCondition;
//MIME可消费匹配
private final ConsumesRequestCondition consumesCondition;
//MIME生成匹配
private final ProducesRequestCondition producesCondition;
// 请求条件容器
private final RequestConditionHolder customConditionHolder;
// 这里如果有多个请求映射有URL冲突,则进行合并
@Override
public RequestMappingInfo combine(RequestMappingInfo other) {
String name = combineNames(other);
PatternsRequestCondition patterns = this.patternsCondition.combine(other.patternsCondition);
RequestMethodsRequestCondition methods = this.methodsCondition.combine(other.methodsCondition);
ParamsRequestCondition params = this.paramsCondition.combine(other.paramsCondition);
HeadersRequestCondition headers = this.headersCondition.combine(other.headersCondition);
ConsumesRequestCondition consumes = this.consumesCondition.combine(other.consumesCondition);
ProducesRequestCondition produces = this.producesCondition.combine(other.producesCondition);
RequestConditionHolder custom = this.customConditionHolder.combine(other.customConditionHolder);
return new RequestMappingInfo(name, patterns,
methods, params, headers, consumes, produces, custom.getCondition());
}
// 匹配请求条件
@Override
@Nullable
public RequestMappingInfo getMatchingCondition(HttpServletRequest request) {
//请求方法匹配
RequestMethodsRequestCondition methods = this.methodsCondition.getMatchingCondition(request);
if (methods == null) {
return null;
}
ParamsRequestCondition params = this.paramsCondition.getMatchingCondition(request);
if (params == null) {
return null;
}
HeadersRequestCondition headers = this.headersCondition.getMatchingCondition(request);
if (headers == null) {
return null;
}
ConsumesRequestCondition consumes = this.consumesCondition.getMatchingCondition(request);
if (consumes == null) {
return null;
}
ProducesRequestCondition produces = this.producesCondition.getMatchingCondition(request);
if (produces == null) {
return null;
}
PatternsRequestCondition patterns = this.patternsCondition.getMatchingCondition(request);
if (patterns == null) {
return null;
}
RequestConditionHolder custom = this.customConditionHolder.getMatchingCondition(request);
if (custom == null) {
return null;
}
return new RequestMappingInfo(this.name, patterns,
methods, params, headers, consumes, produces, custom.getCondition());
}
}
(3)ParamsRequestCondition 为例,将请求参数转成参数实例
可以参考:https://blog.csdn.net/liuyueyi25/article/details/103671809
//表示是集合
private final Set<ParamExpression> expressions;
//解析表达式
private static Collection<ParamExpression> parseExpressions(String... params) {
Set<ParamExpression> expressions = new LinkedHashSet<>();
for (String param : params) {
expressions.add(new ParamExpression(param));
}
return expressions;
}
//某个接口有多个规则时,进行合并 - 比如类上指定了@RequestMapping的 url 为 root - 而方法上指定的@RequestMapping的 url 为 method - 那么在获取这个接口的 url 匹配规则时,类上扫描一次,方法上扫描一次,这个时候就需要把这两个合并成一个,表示这个接口匹配root/method
@Override
public ParamsRequestCondition combine(ParamsRequestCondition other) {
Set<ParamExpression> set = new LinkedHashSet<>(this.expressions);
set.addAll(other.expressions);
return new ParamsRequestCondition(set);
}
//判断是否成功,失败返回 null;否则,则返回匹配成功的条件
@Override
@Nullable
public ParamsRequestCondition getMatchingCondition(HttpServletRequest request) {
for (ParamExpression expression : this.expressions) {
if (!expression.match(request)) {
return null;
}
}
return this;
}
//多个都满足条件时,用来指定具体选择哪一个.这里具体比较长度,选择路径长度短的一个
@Override
public int compareTo(ParamsRequestCondition other, HttpServletRequest request) {
int result = other.expressions.size() - this.expressions.size();
if (result != 0) {
return result;
}
return (int) (getValueMatchCount(other.expressions) - getValueMatchCount(this.expressions));
}
四、springMVC组件–HandlerAdapter 处理器适配器
(1)HandlerAdapter 接口定义三个方法
public interface HandlerAdapter {
//判断是否支持
boolean supports(Object handler);
//进行处理,即真正的调用对应的方法处理
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
//提供最后更新时间
long getLastModified(HttpServletRequest request, Object handler);
}
(2)AbstractHandlerMethodAdapter–HandlerAdapter的实现类
-
继承了WebContentGenerator
-
实现了HandlerAdapter
@Override
public final boolean supports(Object handler) {
//要求handler必须是HandlerMethod
return (handler instanceof HandlerMethod
// 通过子类实现是否支持
&& supportsInternal((HandlerMethod) handler));
}
// 同样,将处理交给了子类实现
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
(3)WebContentGenerator — AbstractHandlerMethodAdapter的父类
其主要作用是提供了一些初始化的操作
- 请求方法
- 请求Session缓存,Cookies缓存
- 请求头的一些设置信息等等
//设置支持的请求方法
public final void setSupportedMethods(@Nullable String... methods) {
if (!ObjectUtils.isEmpty(methods)) {
this.supportedMethods = new LinkedHashSet<>(Arrays.asList(methods));
}
else {
this.supportedMethods = null;
}
initAllowHeader();
}
//初始化允许的方法
private void initAllowHeader() {
Collection<String> allowedMethods;
if (this.supportedMethods == null) {
allowedMethods = new ArrayList<>(HttpMethod.values().length - 1);
for (HttpMethod method : HttpMethod.values()) {
if (method != HttpMethod.TRACE) {
allowedMethods.add(method.name());
}
}
}
else if (this.supportedMethods.contains(HttpMethod.OPTIONS.name())) {
allowedMethods = this.supportedMethods;
}
else {
allowedMethods = new ArrayList<>(this.supportedMethods);
allowedMethods.add(HttpMethod.OPTIONS.name());
}
this.allowHeader = StringUtils.collectionToCommaDelimitedString(allowedMethods);
}
//请求方法枚举
public enum HttpMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
}
(4)RequestMappingHandlerAdapter–真正的请求映射处理器适配器
- 注意这里面有大量的可以自定义拓展的脱战点
//继承关系,属性等内容
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean {
//方法上是否有@InitBinder注解,即初始化的数据绑定注解
public static final MethodFilter INIT_BINDER_METHODS = method ->
AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);
//方法上是否有@RequestMapping和@ModelAttribute注解
public static final MethodFilter MODEL_ATTRIBUTE_METHODS = method ->
(!AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) &&
AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class));
// 自定义的参数解析器
@Nullable
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
//方法参数处理器
@Nullable
private HandlerMethodArgumentResolverComposite argumentResolvers;
//初始化的方法参数处理器组合
@Nullable
private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;
//自定义的方法返回解析处理器
@Nullable
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
//方法返回处理器组合
@Nullable
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
//模型和视图解析器
@Nullable
private List<ModelAndViewResolver> modelAndViewResolvers;
//上下文处理器
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
//HTTP消息转换器
private List<HttpMessageConverter<?>> messageConverters;
//请求响应体增强
private List<Object> requestResponseBodyAdvice = new ArrayList<>();
//Web绑定初始化
@Nullable
private WebBindingInitializer webBindingInitializer;
//异步托线程线程池
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("MvcAsync");
//异步线程池超时时间
@Nullable
private Long asyncRequestTimeout;
//可回调的处理器
private CallableProcessingInterceptor[] callableInterceptors = new CallableProcessingInterceptor[0];
//延迟处理器
private DeferredResultProcessingInterceptor[] deferredResultInterceptors = new DeferredResultProcessingInterceptor[0];
//Reactive适配注册器
private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
//是否忽略默认的重定向
private boolean ignoreDefaultModelOnRedirect = false;
//Session缓存处理器
private int cacheSecondsForSessionAttributeHandlers = 0;
//Session同步器
private boolean synchronizeOnSession = false;
//Session属性缓存
private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore();
//参数名发现者
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
// Web配置类
@Nullable
private ConfigurableBeanFactory beanFactory;
//Session属性处理器容器
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache = new ConcurrentHashMap<>(64);
//初始化绑定缓存容器
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap<>(64);
//初始化增强缓存容器
private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache = new LinkedHashMap<>();
//模型属性缓存容器
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap<>(64);
//模型属性增强缓存容器
private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache = new LinkedHashMap<>();
}
//后置的属性配置集合
@Override
public void afterPropertiesSet() {
// 初始化Controller增强缓存
initControllerAdviceCache();
//方法参数解析器
if (this.argumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
//参数初始化绑定解析器
if (this.initBinderArgumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
//返回值处理器
if (this.returnValueHandlers == null) {
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
// Controller类增强缓存
private void initControllerAdviceCache() {
if (getApplicationContext() == null) {
return;
}
// 从ApplicationContext中获取ControllerAdviceBean
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
AnnotationAwareOrderComparator.sort(adviceBeans);
List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
//遍历处理项目中所有的ControllerAdviceBean
for (ControllerAdviceBean adviceBean : adviceBeans) {
Class<?> beanType = adviceBean.getBeanType();
if (beanType == null) {
throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
}
//获取方法上包含RequestMapping和ModelAttribute注解的方法集
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
if (!attrMethods.isEmpty()) {
//将Bean和方法缓存到modelAttributeAdviceCache中
this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
}
// 获取方法上包含InitBinder注解的方法集
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
if (!binderMethods.isEmpty()) {
//将Bean和方法缓存到modelAttributeAdviceCache中
this.initBinderAdviceCache.put(adviceBean, binderMethods);
}
//类上包含@RequestBodyAdvice注解,讲类存放到ResponseBodyAdviceBeans
// 注解的作用是请求体的增强处理,
if (RequestBodyAdvice.class.isAssignableFrom(beanType)
|| ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
requestResponseBodyAdviceBeans.add(adviceBean);
}
}
if (!requestResponseBodyAdviceBeans.isEmpty()) {
this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
}
}
// 默认的方法参数处理器,使用时可以自定义
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
//默认的或者自定义的方法参数解析器都需要实现HandlerMethodArgumentResolver接口
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
//@RqeustParam 注解参数解析处理
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
//PathVariable 注解参数解析处理
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new PathVariableMapMethodArgumentResolver());
//@MatrixVariable 注解参数解析处理
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
//@ModelAttribute 注解参数解析
resolvers.add(new ServletModelAttributeMethodProcessor(false));
//@RequestBody 注解参数解析
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
//@RequestPart 注解
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
//@RequestHeader注解
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
//@CookieValue 注解
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
//@Value 注解
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
//@SessionAttribute 注解
resolvers.add(new SessionAttributeMethodArgumentResolver());
//@RequestAttribute注解
resolvers.add(new RequestAttributeMethodArgumentResolver());
//ServletRequest类型的参数处理
resolvers.add(new ServletRequestMethodArgumentResolver());
//ServletResponse响应参数处理
resolvers.add(new ServletResponseMethodArgumentResolver());
//RequestEntity等请求实体处理
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
//RedirectAttributes类型处理
resolvers.add(new RedirectAttributes());
//Model类参数
resolvers.add(new ModelMethodProcessor());
//Map类型参数
resolvers.add(new MapMethodProcessor());
//Errors类型参数
resolvers.add(new ErrorsMethodArgumentResolver());
//SessionStatus类型参数
resolvers.add(new SessionStatusMethodArgumentResolver());
//UriComponentsBuilder类型参数
resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
// 配置的用户自定义的参数解析器
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));
return resolvers;
}
//默认的初始化绑定参数处理
private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
//参数绑定处理器
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new PathVariableMapMethodArgumentResolver());
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new SessionAttributeMethodArgumentResolver());
resolvers.add(new RequestAttributeMethodArgumentResolver());
// Type-based argument resolution
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
//自定义的参数绑定
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
return resolvers;
}
//默认的返回值处理器
private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();
//ModeAndView类型返回
handlers.add(new ModelAndViewMethodReturnValueHandler());
handlers.add(new ModelMethodProcessor());
handlers.add(new ViewMethodReturnValueHandler());
//ResponseEntity类型返回,即采用返回对象的形式,注意需要设置解析器,默认是json处理器。可以用消息转换
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
//IO流的形式的返回处理
handlers.add(new StreamingResponseBodyReturnValueHandler());
//HttpEntity响应体的返回处理
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
//HttpHeaders响应头的返回处理
handlers.add(new HttpHeadersReturnValueHandler());
//支持Callable类型的返回,即异步响应返回
handlers.add(new CallableMethodReturnValueHandler());
//支持延迟结果响应
handlers.add(new DeferredResultMethodReturnValueHandler());
//支持异步的方法返回
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
//@ModelAttribute注解
handlers.add(new ModelAttributeMethodProcessor(false));
//@ResponseBody注解的返回,需要默认或者自定义的序列化转换器,例如JSON
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
//String类型的View名称,用于直接返回到对应的页面上
handlers.add(new ViewNameMethodReturnValueHandler());
//Map类型的返回处理
handlers.add(new MapMethodProcessor());
// 用户自定义的返回处理器
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
// Catch-all
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
}else {
handlers.add(new ModelAttributeMethodProcessor(true));
}
return handlers;
}
//内部缓存处理,即如果Session缓存或者响应缓存,则直接使用缓存
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
// 异步的Session处理
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
} else {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}else {
//调用方法处理器
mav = invokeHandlerMethod(request, response, handlerMethod);
}
// 请求头包含Cache 则进行Session缓存
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
} else {
//准备响应结果
prepareResponse(response);
}
}
return mav;
}
//处理方法调用
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//组装ServletWebRequest
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//WebDataBinderFactory: Web内数据绑定工厂
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
//ModelFactory : Model处理工厂
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
//ServletInvocableHandlerMethod
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
//数据绑定
invocableMethod.setDataBinderFactory(binderFactory);
//设置参数发现者
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
//ModelAndViewContainer
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
//异步的Web请求
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
//异步的Web管理器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(
this.deferredResultInterceptors);
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//重点关注方法:真实调用Controller方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
//获取返回值
return getModelAndView(mavContainer, modelFactory, webRequest);
}finally {
//调用结束
webRequest.requestCompleted();
}
}
//获取模型和对应的视图
@Nullable
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
//根据Web请求,更新Model工厂
modelFactory.updateModel(webRequest, mavContainer);
if (mavContainer.isRequestHandled()) {
return null;
}
//ModelMap:从ModelAndView中获取ModelMap
ModelMap model = mavContainer.getModel();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
}
return mav;
}
ServletInvocableHandlerMethod–真正调用并返回处理结果的数据
//ServletInvocableHandlerMethod#invokeAndHandle
public void invokeAndHandle(ServletWebRequest webRequest, //请求和响应参数
ModelAndViewContainer mavContainer, //ModelAndView容器
Object... providedArgs // 请求参数
) throws Exception {
//调用Controller代理类的处理方法,获取到对应的结果
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
//设置返回状态
setResponseStatus(webRequest);
//如果无返回值
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
//设置
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
//通过返回结果处理器对结果进行处理
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
//处理请求并获得响应,这里真正的调用了Controller代理类的对应的处理方法
//InvocableHandlerMethod#invokeForRequest
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//通过调用父类InvocableHandlerMethod的方法
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
return doInvoke(args);
}
//真正执行的方法
@Nullable
protected Object doInvoke(Object... args) throws Exception {
//通过反射,修改方法的访问属性
ReflectionUtils.makeAccessible(getBridgedMethod());
//通过Method对象调用方法
return getBridgedMethod().invoke(getBean(), args);
//忽略某些异常捕获代码
}
// HandlerMethod 类 --- InvocableHandlerMethod的父类
public class HandlerMethod {
//代理实体
private final Object bean;
//对象工厂
@Nullable
private final BeanFactory beanFactory;
//方法的类型
private final Class<?> beanType;
//方法
private final Method method;
//方法的桥(即从Method的实例对象候选集合中获取真正的实例类)
private final Method bridgedMethod;
//方法的参数集
private final MethodParameter[] parameters;
//Http的返回状态
@Nullable
private HttpStatus responseStatus;
//响应的MVC
@Nullable
private String responseStatusReason;
//处理方法,由前面的设置
@Nullable
private HandlerMethod resolvedFromHandlerMethod;
//带注解的参数
@Nullable
private volatile List<Annotation[][]> interfaceParameterAnnotations;
}
//从若干候选方法中获取
@Nullable
private static Method searchCandidates(List<Method> candidateMethods, Method bridgeMethod) {
if (candidateMethods.isEmpty()) {
return null;
}
Method previousMethod = null;
boolean sameSig = true;
for (Method candidateMethod : candidateMethods) {
if (isBridgeMethodFor(bridgeMethod, candidateMethod, bridgeMethod.getDeclaringClass())) {
return candidateMethod;
}
else if (previousMethod != null) {
sameSig = sameSig &&
Arrays.equals(candidateMethod.getGenericParameterTypes(), previousMethod.getGenericParameterTypes());
}
previousMethod = candidateMethod;
}
return (sameSig ? candidateMethods.get(0) : null);
}
五、SpringMVC组件–ViewResolver视图解析器
-
ViewResolver就一个接口:resolveViewName(String viewName, Locale locale)
-
抽象子类AbstractCachingViewResolver – 主要处理缓存
-
抽象子类AbstractTemplateViewResolver–抽象的模板视图解析器
-
FreeMarkerViewResolver/GroovyMarkupViewResolver/MustacheViewResolver等视图解析
-
UrlBasedViewResolver–基于URL的视图解析器
UrlBasedViewResolver-- 基于URL的视图解析器
public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {
//重定向形式
public static final String REDIRECT_URL_PREFIX = "redirect:";
//转发形式
public static final String FORWARD_URL_PREFIX = "forward:";
//视图类
@Nullable
private Class<?> viewClass;
//前缀
private String prefix = "";
//后缀
private String suffix = "";
//上下文类型
@Nullable
private String contentType;
//重定向的域名
@Nullable
private String[] redirectHosts;
//请求上下文的参数
@Nullable
private String requestContextAttribute;
//属性集合
private final Map<String, Object> staticAttributes = new HashMap<>();
//暴露的上下文的Bean名称
@Nullable
private String[] exposedContextBeanNames;
//视图名称集合
@Nullable
private String[] viewNames;
@Nullable
private Boolean exposePathVariables;
@Nullable
private Boolean exposeContextBeansAsAttributes;
private int order = Ordered.LOWEST_PRECEDENCE;
private boolean redirectContextRelative = true;
private boolean redirectHttp10Compatible = true;
}