溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringMVC源碼解析 一

發(fā)布時間:2020-06-18 10:49:11 來源:網絡 閱讀:208 作者:nineteens 欄目:編程語言

  當服務器接收到從瀏覽器發(fā)送的一個請求后, 首先進入HttpServlet#service()方法中

  HttpServlet#service()方法實現(xiàn):

  @Override

  public void service(ServletRequest req, ServletResponse res)

  throws ServletException, IOException {

  HttpServletRequest request;

  HttpServletResponse response;

  try {

  request = (HttpServletRequest) req;

  response = (HttpServletResponse) res;

  } catch (ClassCastException e) {

  throw new ServletException(lStrings.getString("http.non_http"));

  }

  service(request, response);

  }

  protected void service(HttpServletRequest req, HttpServletResponse resp)

  throws ServletException, IOException {

  String method = req.getMethod();

  if (method.equals(METHOD_GET)) {

  long lastModified = getLastModified(req);

  if (lastModified == -1) {

  // servlet doesn't support if-modified-since, no reason

  // to go through further expensive logic

  doGet(req, resp);

  } else {

  long ifModifiedSince;

  try {

  ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

  } catch (IllegalArgumentException iae) {

  // Invalid date header - proceed as if none was set

  ifModifiedSince = -1;

  }

  if (ifModifiedSince < (lastModified / 1000 * 1000)) {

  // If the servlet mod time is later, call doGet()

  // Round down to the nearest second for a proper compare

  // A ifModifiedSince of -1 will always be less

  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);

  }

  }

  在HttpServlet#service(request, response)中調用根據(jù)請求類型調用不同的實現(xiàn)方法, doGet, doPost等; 這里發(fā)送的是get請求, 因此看doGet()的實現(xiàn);

  FrameworkServlet#doGet()方法的實現(xiàn):

  @Override

  protected final void doGet(HttpServletRequest request, HttpServletResponse response)

  throws ServletException, IOException {

  proce***equest(request, response);

  }

  FrameworkServlet#proce***equest()方法實現(xiàn):

  protected final void proce***equest(HttpServletRequest request, HttpServletResponse response)

  throws ServletException, IOException {

  long startTime = System.currentTimeMillis();

  Throwable failureCause = null;

  LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();

  LocaleContext localeContext = buildLocaleContext(request);

  RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();

  ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

  WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

  asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

  initContextHolders(request, localeContext, requestAttributes);

  try {

  /**

  * 請求邏輯處理

  * {@link DispatcherServlet#doService(HttpServletRequest,HttpServletResponse)}

  */

  doService(request, response);

  }

  . . . . . .

  }

  DispatcherServlet#doService()方法實現(xiàn)

  @Override

  protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {

  if (logger.isDebugEnabled()) {

  String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";

  logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +

  " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");

  }

  // 設置快照

  Map 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());

  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(request, response);

  }

  finally {

  if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {

  //使用快照恢復Request屬性

  if (attributesSnapshot != null) {

  restoreAttributesAfterInclude(request, attributesSnapshot);

  }

  }

  }

  }

  DispatcherServlet#doDispatch()方法實現(xiàn)

  protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

  HttpServletRequest processedRequest = request;

  HandlerExecutionChain mappedHandler = null;

  boolean multipartRequestParsed = false;

  WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

  try {鄭州人流醫(yī)院 http://www.zykdfk.com/

  ModelAndView mv = null; //封裝view和數(shù)據(jù)信息

  Exception dispatchException = null; //封裝異常信息

  try {

  processedRequest = checkMultipart(request);

  multipartRequestParsed = (processedRequest != request);

  /**

  * 1. 獲取處理器

  * mappedHandler: HandlerExecutionChain

  */

  mappedHandler = getHandler(processedRequest);

  if (mappedHandler == null) {

  noHandlerFound(processedRequest, response);

  return;

  }

  /**

  * 2. 獲取適配器

  */

  HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

  // 如果處理程序支持,則處理最后修改的標頭

  String method = request.getMethod();

  boolean isGet = "GET".equals(method);

  if (isGet || "HEAD".equals(method)) {

  long lastModified = ha.getLastModified(request, mappedHandler.getHandler());

  if (logger.isDebugEnabled()) {

  logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);

  }

  if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {

  return;

  }

  }

  /**

  * 執(zhí)行HandlerExecutionChain中的攔截器

  */

  if (!mappedHandler.applyPreHandle(processedRequest, response)) {

  return;

  }

  /**

  * 3. 通過適配器執(zhí)行處理器, 也就是我們編寫的Controller類; 注意: 這里調用的是適配器的handle()方法

  * {@link AbstractHandlerMethodAdapter#handle(HttpServletRequest, HttpServletResponse, Object)}

  *

  * mv: ModelAndView實例{@link AbstractHandlerMethodAdapter#handle(HttpServletRequest,HttpServletResponse, Object)}

  */

  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) {

  // 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);

  }

  /**

  * 4. 視圖解析

  */

  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);

  }

  }

  }

  }

  分析(注: 以下模塊解析比較復雜, 拆分為不同播客分析):

  根據(jù)請求信息獲取對應處理器

  根據(jù)映射處理器獲取對應的適配器

  通過適配器執(zhí)行處理器, 也就是編寫的Controller類中的相應方法

  視圖解析

  請求解析過程圖


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI