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

image.png

请求分发控制器

  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  2. HttpServletRequest processedRequest = request;
  3. HandlerExecutionChain mappedHandler = null;
  4. boolean multipartRequestParsed = false;
  5. WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
  6. try {
  7. ModelAndView mv = null;
  8. Exception dispatchException = null;
  9. try {
  10. //检查是否是二进制文件请求:如图片上传等
  11. processedRequest = checkMultipart(request);
  12. multipartRequestParsed = (processedRequest != request);
  13. //1.寻找Controller处理类的方法和拦截器封装到执行链中HandlerExecutionChain
  14. mappedHandler = getHandler(processedRequest);
  15. if (mappedHandler == null) {
  16. noHandlerFound(processedRequest, response);
  17. return;
  18. }
  19. //2.寻找处理器Controller的适配器
  20. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
  21. // Process last-modified header, if supported by the handler.
  22. String method = request.getMethod();
  23. boolean isGet = "GET".equals(method);
  24. if (isGet || "HEAD".equals(method)) {
  25. long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
  26. if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
  27. return;
  28. }
  29. }
  30. //3.执行拦截器
  31. if (!mappedHandler.applyPreHandle(processedRequest, response)) {
  32. return;
  33. }
  34. //4.执行Controller
  35. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  36. if (asyncManager.isConcurrentHandlingStarted()) {
  37. return;
  38. }
  39. applyDefaultViewName(processedRequest, mv);
  40. mappedHandler.applyPostHandle(processedRequest, response, mv);
  41. }
  42. catch (Exception ex) {
  43. dispatchException = ex;
  44. }
  45. catch (Throwable err) {
  46. // As of 4.3, we're processing Errors thrown from handler methods as well,
  47. // making them available for @ExceptionHandler methods and other scenarios.
  48. dispatchException = new NestedServletException("Handler dispatch failed", err);
  49. }
  50. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
  51. }
  52. catch (Exception ex) {
  53. triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
  54. }
  55. catch (Throwable err) {
  56. triggerAfterCompletion(processedRequest, response, mappedHandler,
  57. new NestedServletException("Handler processing failed", err));
  58. }
  59. finally {
  60. if (asyncManager.isConcurrentHandlingStarted()) {
  61. // Instead of postHandle and afterCompletion
  62. if (mappedHandler != null) {
  63. mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
  64. }
  65. }
  66. else {
  67. // Clean up any resources used by a multipart request.
  68. if (multipartRequestParsed) {
  69. cleanupMultipart(processedRequest);
  70. }
  71. }
  72. }
  73. }

寻找Controller处理类的方法

image.png

SpringMVC实现方式

1.注解
2.BeanName

BeanNameUrlHandlerMapping

BeanName方式的实现接口

RequestMappingHandlerMapping

注解方式的实现接口

  1. protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  2. //handlerMappings记录了BeanName和注解方式的映射
  3. if (this.handlerMappings != null) {
  4. for (HandlerMapping mapping : this.handlerMappings) {
  5. //便利查找Controller,因为有可能是通过BeanName方式实现的Controller,也有可能是通过注解
  6. //HandlerExecutionChain 执行链,在调用Controller的时候,有可能存在拦截器的
  7. HandlerExecutionChain handler = mapping.getHandler(request);
  8. if (handler != null) {
  9. return handler;
  10. }
  11. }
  12. }
  13. return null;
  14. }

org.springframework.web.servlet.HandlerMapping#getHandler
org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler

  1. public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  2. //private final Map<String, Object> handlerMap = new LinkedHashMap<>();
  3. //拿到请求的Controller
  4. Object handler = getHandlerInternal(request);
  5. if (handler == null) {
  6. handler = getDefaultHandler();
  7. }
  8. if (handler == null) {
  9. return null;
  10. }
  11. // Bean name or resolved handler?
  12. if (handler instanceof String) {
  13. String handlerName = (String) handler;
  14. handler = obtainApplicationContext().getBean(handlerName);
  15. }
  16. HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
  17. if (logger.isTraceEnabled()) {
  18. logger.trace("Mapped to " + handler);
  19. }
  20. else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
  21. logger.debug("Mapped to " + executionChain.getHandler());
  22. }
  23. if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
  24. CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
  25. CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
  26. config = (config != null ? config.combine(handlerConfig) : handlerConfig);
  27. executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
  28. }
  29. return executionChain;
  30. }

org.springframework.web.servlet.HandlerMapping#getHandler
org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#getHandlerInternal

  1. protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
  2. //拿到请求的url
  3. String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
  4. request.setAttribute(LOOKUP_PATH, lookupPath);
  5. //通过url拿到请求的Controller
  6. Object handler = lookupHandler(lookupPath, request);
  7. if (handler == null) {
  8. // We need to care for the default handler directly, since we need to
  9. // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
  10. Object rawHandler = null;
  11. if ("/".equals(lookupPath)) {
  12. rawHandler = getRootHandler();
  13. }
  14. if (rawHandler == null) {
  15. rawHandler = getDefaultHandler();
  16. }
  17. if (rawHandler != null) {
  18. // Bean name or resolved handler?
  19. if (rawHandler instanceof String) {
  20. String handlerName = (String) rawHandler;
  21. rawHandler = obtainApplicationContext().getBean(handlerName);
  22. }
  23. validateHandler(rawHandler, request);
  24. handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
  25. }
  26. }
  27. return handler;
  28. }

寻找Controller的适配器

org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
SpringMVC有三种不同的实现方式
1.implements Controller
2.implements HttpRequestHandler
3.注解@Controller
image.png

  1. protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
  2. if (this.handlerAdapters != null) {
  3. for (HandlerAdapter adapter : this.handlerAdapters) {
  4. //判断一下是不是HandlerMethod
  5. //三种实现方式
  6. if (adapter.supports(handler)) {
  7. return adapter;
  8. }
  9. }
  10. }
  11. throw new ServletException("No adapter for handler [" + handler +
  12. "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
  13. }

implements Controller方式

  1. public class SimpleControllerHandlerAdapter implements HandlerAdapter {
  2. @Override
  3. public boolean supports(Object handler) {
  4. return (handler instanceof Controller);
  5. }
  6. }

implements HttpRequestHandler

  1. public class HttpRequestHandlerAdapter implements HandlerAdapter {
  2. @Override
  3. public boolean supports(Object handler) {
  4. return (handler instanceof HttpRequestHandler);
  5. }
  6. }

注解@Controller

  1. public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
  2. @Override
  3. public final boolean supports(Object handler) {
  4. return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
  5. }
  6. }

执行拦截器

org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle

  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  2. //执行拦截器
  3. if (!mappedHandler.applyPreHandle(processedRequest, response)) {
  4. return;
  5. }
  6. // 执行Controller
  7. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  8. }

执行Controller

  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  2. //执行拦截器
  3. if (!mappedHandler.applyPreHandle(processedRequest, response)) {
  4. return;
  5. }
  6. // 执行Controller
  7. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  8. }

org.springframework.web.servlet.HandlerAdapter#handle

  1. public interface HandlerAdapter {
  2. //判断处理3种实现方式的接口
  3. boolean supports(Object handler);
  4. //执行Controller
  5. @Nullable
  6. ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
  7. long getLastModified(HttpServletRequest request, Object handler);
  8. }

AbstractHandlerMethodAdapter

org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter

  1. @Override
  2. protected ModelAndView handleInternal(HttpServletRequest request,
  3. HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
  4. ModelAndView mav;
  5. checkRequest(request);
  6. if (this.synchronizeOnSession) {
  7. HttpSession session = request.getSession(false);
  8. if (session != null) {
  9. Object mutex = WebUtils.getSessionMutex(session);
  10. synchronized (mutex) {
  11. mav = invokeHandlerMethod(request, response, handlerMethod);
  12. }
  13. }
  14. else {
  15. mav = invokeHandlerMethod(request, response, handlerMethod);
  16. }
  17. }
  18. else {
  19. //关键代码,调用Controller
  20. mav = invokeHandlerMethod(request, response, handlerMethod);
  21. }
  22. if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
  23. if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
  24. applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
  25. }
  26. else {
  27. prepareResponse(response);
  28. }
  29. }
  30. return mav;
  31. }

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

  1. public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
  2. Object... providedArgs) throws Exception {
  3. //设置参数,参数赋值
  4. Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
  5. setResponseStatus(webRequest);
  6. if (returnValue == null) {
  7. if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
  8. disableContentCachingIfNecessary(webRequest);
  9. mavContainer.setRequestHandled(true);
  10. return;
  11. }
  12. }
  13. else if (StringUtils.hasText(getResponseStatusReason())) {
  14. mavContainer.setRequestHandled(true);
  15. return;
  16. }
  17. mavContainer.setRequestHandled(false);
  18. Assert.state(this.returnValueHandlers != null, "No return value handlers");
  19. try {
  20. this.returnValueHandlers.handleReturnValue(
  21. returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
  22. }
  23. catch (Exception ex) {
  24. if (logger.isTraceEnabled()) {
  25. logger.trace(formatErrorForReturnValue(returnValue), ex);
  26. }
  27. throw ex;
  28. }
  29. }

参数赋值,返回实参数组,调用Controller

  1. public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
  2. //参数赋值
  3. Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
  4. if (this.logger.isTraceEnabled()) {
  5. this.logger.trace("Arguments: " + Arrays.toString(args));
  6. }
  7. //反射调用Controller方法
  8. return this.doInvoke(args);
  9. }

执行链路