又是美好的一天呀~
个人博客地址: huanghong.top
本文预估阅读时长为40分钟左右~
本文关联文章 Spring全局异常处理的使用及源码分析
往下看看~
SpringMVC源码分析
执行链路图
初始化
项目初始化并不会直接初始化WebApplicationContext,当服务端第一次接收到客户端请求时,进行Servlet初始化。
init
//javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
initServletBean
//org.springframework.web.servlet.FrameworkServlet#initServletBean
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
if (logger.isInfoEnabled()) {
logger.info("Initializing Servlet '" + getServletName() + "'");
}
long startTime = System.currentTimeMillis();
try {
//执行web上下文初始化
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
catch (ServletException | RuntimeException ex) {
logger.error("Context initialization failed", ex);
throw ex;
}
if (logger.isDebugEnabled()) {
String value = this.enableLoggingRequestDetails ?
"shown which may lead to unsafe logging of potentially sensitive data" :
"masked to prevent unsafe logging of potentially sensitive data";
logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +
"': request parameters and headers will be " + value);
}
if (logger.isInfoEnabled()) {
logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
}
}
DispatcherServlet.properties
org\springframework\spring-webmvc\5.3.13\spring-webmvc-5.3.13.jar!\org\springframework\web\servlet\DispatcherServlet.properties
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
org.springframework.web.servlet.function.support.RouterFunctionMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
org.springframework.web.servlet.function.support.HandlerFunctionAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
onRefresh
//org.springframework.web.servlet.DispatcherServlet#onRefresh
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
//org.springframework.web.servlet.DispatcherServlet#initStrategies
protected void initStrategies(ApplicationContext context) {
//初始化文件上传解析器
//默认赋值 org.springframework.web.multipart.support.StandardServletMultipartResolver
initMultipartResolver(context);
//初始化国际化语言解析器
//默认赋值 org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
initLocaleResolver(context);
//初始化主题解析器
//默认赋值 org.springframework.web.servlet.theme.FixedThemeResolver
initThemeResolver(context);
//初始化处理映射器
initHandlerMappings(context);
//初始化处理适配器
initHandlerAdapters(context);
//初始化异常处理解析器(@ControllerAdvice)
//默认赋值 org.springframework.web.servlet.HandlerExceptionResolver接口子类
//具体解析步骤
initHandlerExceptionResolvers(context);
//初始化视图转换器
//默认赋值 org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
initRequestToViewNameTranslator(context);
//初始化视图解析器
//默认赋值 org.springframework.web.servlet.ViewResolver接口子类
initViewResolvers(context);
//初始化flash管理器
//默认赋值 org.springframework.web.servlet.support.SessionFlashMapManager
initFlashMapManager(context);
}
initHandlerMappings
//org.springframework.web.servlet.DispatcherServlet#initHandlerMappings
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
//是否检查所有处理器映射器 包含父类中的上下文
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
//获取全局上下文所有的处理器映射器
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
//处理器映射器结果集不为空
if (!matchingBeans.isEmpty()) {
//赋值
this.handlerMappings = new ArrayList<>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
//排序
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
else {
try {
//没有手动配置则为空,后续会添加一个默认的处理器映射器
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}
// Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
//如果处理器映射器为空
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");
}
}
//遍历处理器映射器结果集
for (HandlerMapping mapping : this.handlerMappings) {
//存在处理器映射器使用路径解析模式则赋值parseRequestPath为true
if (mapping.usesPathPatterns()) {
this.parseRequestPath = true;
break;
}
}
}
//org.springframework.web.servlet.handler.AbstractHandlerMapping#usesPathPatterns
public boolean usesPathPatterns() {
return getPatternParser() != null;
}
默认加载的HandlerMapping(5个)
-
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerMapping(order:0)
-
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#beanNameHandlerMapping(order:2)
-
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#routerFunctionMapping(order:3)
-
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry#getHandlerMapping
-> SimpleUrlHandlerMapping(order:Ordered.LOWEST_PRECEDENCE - 1)
-
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#welcomePageHandlerMapping(order:Ordered.LOWEST_PRECEDENCE)
继承org.springframework.web.servlet.handler.AbstractHandlerMapping的order属性
getDefaultStrategies
//org.springframework.web.servlet.DispatcherServlet#getDefaultStrategies
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
if (defaultStrategies == null) {
try {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
//加载DispatcherServlet同级包中的DispatcherServlet.properties
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
}
}
//获取接口名作为key
String key = strategyInterface.getName();
//在DispatcherServlet.properties中获取对应的value值
String value = defaultStrategies.getProperty(key);
if (value != null) {
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List<T> strategies = new ArrayList<>(classNames.length);
for (String className : classNames) {
try {
//通过反射构建对应类型对象实例并添加进策略中
Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
Object strategy = createDefaultStrategy(context, clazz);
strategies.add((T) strategy);
}
catch (ClassNotFoundException ex) {
throw new BeanInitializationException(
"Could not find DispatcherServlet's default strategy class [" + className +
"] for interface [" + key + "]", ex);
}
catch (LinkageError err) {
throw new BeanInitializationException(
"Unresolvable class definition for DispatcherServlet's default strategy class [" +
className + "] for interface [" + key + "]", err);
}
}
return strategies;
}
else {
return Collections.emptyList();
}
}
initHandlerAdapters
//org.springframework.web.servlet.DispatcherServlet#initHandlerAdapters
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;
//是否检查所有处理器适配器 包含父类中的上下文
if (this.detectAllHandlerAdapters) {
// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
//获取全局上下文所有的处理器适配器
Map<String, HandlerAdapter> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
//处理器适配器结果集不为空
if (!matchingBeans.isEmpty()) {
//赋值
this.handlerAdapters = new ArrayList<>(matchingBeans.values());
// We keep HandlerAdapters in sorted order.
//排序
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
}
else {
try {
//没有手动配置则为空,后续会添加一个默认的处理器适配器
HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
this.handlerAdapters = Collections.singletonList(ha);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerAdapter later.
}
}
// Ensure we have at least some HandlerAdapters, by registering
// default HandlerAdapters if no other adapters are found.
//如果处理器适配器为空
if (this.handlerAdapters == null) {
//获取默认值
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
if (logger.isTraceEnabled()) {
logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
"': using default strategies from DispatcherServlet.properties");
}
}
}
默认加载的HandlerAdapter(4个)
- org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter
- org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#handlerFunctionAdapter
- org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#httpRequestHandlerAdapter
- org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#simpleControllerHandlerAdapter
doService
HTTP请求处理链路
- 客户端HTTP请求
- tomcat起一个线程负责处理请求
- ApplicationFilterChain#internalDoFilter过滤器链处理请求
- HttpServlet#service处理请求
- org.springframework.web.servlet.DispatcherServlet#doService
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//日志记录
logRequest(request);
//保存原request属性,用于请求执行完属性清理后的属性恢复
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap<>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
//是否开启属性清理功能 or 属性名的前缀为org.springframework.web.servlet
if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
//放入缓存中
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
//设置MVC相关资源属性 用于后续请求过程的处理
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);
}
//是否进行路径解析(默认不进行)
RequestPath previousRequestPath = null;
if (this.parseRequestPath) {
previousRequestPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
ServletRequestPathUtils.parseAndCache(request);
}
try {
//逻辑处理
doDispatch(request, response);
}
finally {
//request属性恢复
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
//原request请求路径恢复
if (this.parseRequestPath) {
ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
}
}
}
doDispatch
//org.springframework.web.servlet.DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
//多文档类型请求
boolean multipartRequestParsed = false;
//web异步处理管理
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//检查是否为多文档类型请求 检查请求头中的Content-Type属性是否为multipart/form-data or multipart/开头
//若为多文档类型请求则构建一个StandardMultipartHttpServletRequest对象
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
//为当前request选择一个处理器,维护了一个最适配的HandlerMethod和对应的拦截器链
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
//没有找到对应的处理器,返回404
noHandlerFound(processedRequest, response);
return;
}
//为当前request选择一个处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//如果是GET或HEAD请求
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
//获取最后修改时间
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
//调用checkNotModified方法验证 http 请求头中的“If-Modified-Since”的时间进行对比,判断页面是否更新过。
//如果有更新才执行具体的Controller, 没有更新则响应304状态码信息(HTTP 304: Not Modified )
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//拦截器的前置处理
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//真正的请求执行逻辑
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//存在并发处理的情况直接结束处理
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//使用默认的视图页面 mv不为null && 没有对应视图则使用默认视图
applyDefaultViewName(processedRequest, mv);
//拦截器的后置处理
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
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 {
//文档类型请求清除所有request属性资源
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
getHandler
//org.springframework.web.servlet.DispatcherServlet#getHandler
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
//遍历处理器映射器 默认由优先级最高的requestMappingHandlerMapping来进行处理
for (HandlerMapping mapping : this.handlerMappings) {
//获取处理器
//HandlerExecutionChain包含HandlerMethod和Interceptors拦截器链
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
//处理器不为空则返回
return handler;
}
}
}
return null;
}
getHandler
//org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//获取URI最合适的HandlerMethod
Object handler = getHandlerInternal(request);
//handler为空获取默认的处理器 默认的handler也为null
if (handler == null) {
handler = getDefaultHandler();
}
//handler为空直接返回
if (handler == null) {
return null;
}
//handler如果是字符串对象,则通过上下文获取Handler实例
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
//确保存在缓存请求路径
if (!ServletRequestPathUtils.hasCachedPath(request)) {
//否则初始化请求路径
initLookupPath(request);
}
//获取封装拦截器链后的HandlerMethod对象
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) {
logger.debug("Mapped to " + executionChain.getHandler());
}
//跨域处理
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = getCorsConfiguration(handler, request);
if (getCorsConfigurationSource() != null) {
CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
config = (globalConfig != null ? globalConfig.combine(config) : config);
}
if (config != null) {
config.validateAllowCredentials();
}
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
getHandlerInternal
//org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//getPathWithinApplication获取contextPath + requestUri
String lookupPath = initLookupPath(request);
this.mappingRegistry.acquireReadLock();
try {
//获取URI最合适的HandlerMethod
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
lookupHandlerMethod
//org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<Match> matches = new ArrayList<>();
//获取uri对应RequestInfoMapping对象集合
List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
if (directPathMatches != null) {
//获取uri对应HandlerMethod包装对象,放入本地缓存
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
}
if (!matches.isEmpty()) {
//获取最适配的HandlerMethod包装类
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
//HandlerMethod包装类数量大于1的话进行排序后取第一个HandlerMethod包装类(请求条件数量更多的优先-TODO)
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)) {
for (Match match : matches) {
if (match.hasCorsConfig()) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
}
}
else {
//抛出排序同级异常
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.getHandlerMethod().getMethod();
Method m2 = secondBestMatch.getHandlerMethod().getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
}
//设置HandlerMethod的request属性
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
//路径变量处理
handleMatch(bestMatch.mapping, lookupPath, request);
//返回HandlerMethod
return bestMatch.getHandlerMethod();
}
else {
return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
}
}
getHandlerExecutionChain
//org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//封装HandlerExecutionChain对象
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
//Spring内部维护的一个url匹配拦截器
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(request)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
//添加拦截器
chain.addInterceptor(interceptor);
}
}
return chain;
}
getHandlerAdapter
//org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
//(handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler)) supportsInternal返回true
//返回默认RequestMappingHandlerAdapter
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");
}
applyPreHandle
//org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for (int i = 0; i < this.interceptorList.size(); i++) {
HandlerInterceptor interceptor = this.interceptorList.get(i);
//拦截器前置处理
if (!interceptor.preHandle(request, response, this.handler)) {
//前置处理返回false 则执行拦截器中的afterCompletion方法
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
return true;
}
handleInternal
//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
//检查请求中所支持的方法和是否需要session
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 {
// No HttpSession available -> no mutex necessary
//session为null 直接执行
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
//直接执行HandlerMethod
mav = invokeHandlerMethod(request, response, handlerMethod);
}
//响应头中不包含Cache-Control,响应缓存处理
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
invokeHandlerMethod
//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//构建一个ServletWebRequest对象
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//WebDataBinderFactory为目标对象创建一个WebDataBinder实例
//WebDataBinder继承了DataBinder类,为web请求提供了参数绑定服务
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
//获取ModelFactory
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
// 创建ServletInvocableHandlerMethod对象 ServletInvocableHandlerMethod继承并扩展了InvocableHandlerMethod
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,并初始化Model对象
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
//异步请求相关内容
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
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);
}
//执行并处理请求
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
//返回ModelAndView or null
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
//请求结束回调
webRequest.requestCompleted();
}
}
invokeAndHandle
//org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//执行请求
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
//设置response响应参数
setResponseStatus(webRequest);
//请求返回结果值为空
if (returnValue == null) {
//request类型为not modified || 返回参数不为空 || 请求是否被完整处理
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
//如果是not modified类型请求则进行缓存失效
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 {
//处理返回结果集 RequestResponseBodyMethodProcessor处理ResponseBody结果集
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
invokeForRequest
//org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//参数解析
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
//通过反射执行对应处理器方法
return doInvoke(args);
}
getModelAndView
//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getModelAndView
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
modelFactory.updateModel(webRequest, mavContainer);
//请求被完整处理
if (mavContainer.isRequestHandled()) {
//返回null
return null;
}
//获取ModelMap
ModelMap model = mavContainer.getModel();
//获取ModelAndView对象 封装请求对应视图和数据
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
//设置视图
mav.setView((View) mavContainer.getView());
}
//flash属性填充
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;
}
processDispatchResult
//org.springframework.web.servlet.DispatcherServlet#processDispatchResult
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
//是否为错误视图
boolean errorView = false;
//请求过程异常不为空
if (exception != null) {
//ModelAndViewDefiningException异常处理
if (exception instanceof ModelAndViewDefiningException) {
logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
//其他异常处理
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
//异常处理
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}
//视图渲染
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No view rendering, null ModelAndView returned.");
}
}
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Concurrent handling started during a forward
return;
}
if (mappedHandler != null) {
//拦截器的请求完成之后的处理
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
备注
- HandlerMethod注册逻辑(org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#register)
感谢阅读完本篇文章!!!
个人博客地址: huanghong.top