springmvc
1.springmvc 首先会在初始化的时候将我们的Controller(@Controller)、Mehtod(@RequestMapping)、参数解析成一个HandlerMethod对象
2.在用户发起请求的时候,springmvc会通过DispatcherServlet进行转发:由于DispatcherServlet重写了HttpServelt中的Service方法,然后调用doDispatch
3.通过Request请求的映射路径找到对应的处理方法:返回HandlerMethod对象,然后通过bean的名字通过beanFactory把bean给创建出来,再返回新的HandlerMethod
4.然后便利找handler的适配器,如果有拦截器,先调用拦截器,如果没有,就调用hander
5.调用完hander之后,返回modelandview
请求分发控制器
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);//1.寻找Controller处理类的方法和拦截器封装到执行链中HandlerExecutionChainmappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}//2.寻找处理器Controller的适配器HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// Process last-modified header, if supported by the handler.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;}}//3.执行拦截器if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}//4.执行Controllermv = 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) {// 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 afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}
寻找Controller处理类的方法
SpringMVC实现方式
BeanNameUrlHandlerMapping
RequestMappingHandlerMapping
注解方式的实现接口
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {//handlerMappings记录了BeanName和注解方式的映射if (this.handlerMappings != null) {for (HandlerMapping mapping : this.handlerMappings) {//便利查找Controller,因为有可能是通过BeanName方式实现的Controller,也有可能是通过注解//HandlerExecutionChain 执行链,在调用Controller的时候,有可能存在拦截器的HandlerExecutionChain handler = mapping.getHandler(request);if (handler != null) {return handler;}}}return null;}
org.springframework.web.servlet.HandlerMapping#getHandler
org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {//private final Map<String, Object> handlerMap = new LinkedHashMap<>();//拿到请求的ControllerObject 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 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;}
org.springframework.web.servlet.HandlerMapping#getHandler
org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#getHandlerInternal
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {//拿到请求的urlString lookupPath = getUrlPathHelper().getLookupPathForRequest(request);request.setAttribute(LOOKUP_PATH, lookupPath);//通过url拿到请求的ControllerObject handler = lookupHandler(lookupPath, request);if (handler == null) {// We need to care for the default handler directly, since we need to// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.Object rawHandler = null;if ("/".equals(lookupPath)) {rawHandler = getRootHandler();}if (rawHandler == null) {rawHandler = getDefaultHandler();}if (rawHandler != null) {// Bean name or resolved handler?if (rawHandler instanceof String) {String handlerName = (String) rawHandler;rawHandler = obtainApplicationContext().getBean(handlerName);}validateHandler(rawHandler, request);handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);}}return handler;}
寻找Controller的适配器
org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
SpringMVC有三种不同的实现方式
1.implements Controller
2.implements HttpRequestHandler
3.注解@Controller
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter adapter : this.handlerAdapters) {//判断一下是不是HandlerMethod//三种实现方式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");}
implements Controller方式
public class SimpleControllerHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {return (handler instanceof Controller);}}
implements HttpRequestHandler
public class HttpRequestHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {return (handler instanceof HttpRequestHandler);}}
注解@Controller
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {@Overridepublic final boolean supports(Object handler) {return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));}}
执行拦截器
org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {//执行拦截器if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 执行Controllermv = ha.handle(processedRequest, response, mappedHandler.getHandler());}
执行Controller
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {//执行拦截器if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 执行Controllermv = ha.handle(processedRequest, response, mappedHandler.getHandler());}
org.springframework.web.servlet.HandlerAdapter#handle
public interface HandlerAdapter {//判断处理3种实现方式的接口boolean supports(Object handler);//执行Controller@NullableModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;long getLastModified(HttpServletRequest request, Object handler);}
AbstractHandlerMethodAdapter
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter
@Overrideprotected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav;checkRequest(request);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 {//关键代码,调用Controllermav = invokeHandlerMethod(request, response, handlerMethod);}if (!response.containsHeader(HEADER_CACHE_CONTROL)) {if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);}else {prepareResponse(response);}}return mav;}
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
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);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
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {//参数赋值Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);if (this.logger.isTraceEnabled()) {this.logger.trace("Arguments: " + Arrays.toString(args));}//反射调用Controller方法return this.doInvoke(args);}
