91精品新拍在线观看,91精品一区二区,91精品一区二区三区久久久久,91精品在线播放,91精品中综合久久久久婷婷

<pre id="fhfjj"><ruby id="fhfjj"><var id="fhfjj"></var></ruby></pre>
    <p id="fhfjj"><del id="fhfjj"></del></p>

    <p id="fhfjj"><mark id="fhfjj"><progress id="fhfjj"></progress></mark></p>

      當前位置: 首頁 / 技術分享 / 正文
      SpringMVC源碼解析(四)

      2023-03-09

      視圖 handleradapter 處理器 對象 返回

        4 處理器適配器HandlerAdapter

        4.1 HandlerAdapter源碼分析

        1.在DispatcherServlet類中的doDispatch(request, response)方法中調用getHandlerAdapter(mappedHandler.getHandler())獲取處理器適配器。

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

      // 確定當前請求的處理程序適配器。
      HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
      }
      // ...
      }
      // ...
      }

        2.getHandlerAdapter(Object handler)方法的具體實現見下源代碼。根據Handler找到支持它的HandlerAdapter對象。

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

        3.在SimpleControllerHandlerAdapter類中實現了HandlerAdapter接口中的三個抽象方法。

      public class SimpleControllerHandlerAdapter implements HandlerAdapter {

      @Override
      public boolean supports(Object handler) {
      // 判斷找到的handler是否為Controller類型。HelloController類實現了Controller接口,所以處理器能夠找到該類
      return (handler instanceof Controller);
      }

      @Override
      @Nullable
      public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
      // 通過handler處理器,調用控制器的handlerRequest方法,來處理相應的請求
      return ((Controller) handler).handleRequest(request, response);
      }

      /**
      * 與HttpServlet的getLastModified方法的約定相同。在請求處理之前調用。

      * 返回值將作為Last-Modified報頭發送給HTTP客戶端,并與客戶端返回的If-Modified-Since報頭進行比較。只有在進行了修改后,內容才會重新生成。

      * 參數:request - 當前HTTP請求

      * 返回:上次修改基礎資源的時間,或-1表示必須始終重新生成內容
      */
      @Override
      @SuppressWarnings("deprecation")
      public long getLastModified(HttpServletRequest request, Object handler) {
      if (handler instanceof LastModified) {
      return ((LastModified) handler).getLastModified(request);
      }
      return -1L;
      }

      }

        4.從SimpleControllerHandlerAdapter類中handle方法可以看出,通過HandlerAdapter執行Handler對象,最終得到ModelAndView對象。

      @Override
      @Nullable
      public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
      // handler處理器執行handleRequest方法,主要作用是找到HelloController類中重寫的handleRequest重寫的業務邏輯方法
      return ((Controller) handler).handleRequest(request, response);
      }

        4.2 HandlerAdapter的執行

        DispatcherServlet會根據handlerMapping傳過來的controller與已經注冊好了的HandlerAdapter相匹配,看哪一種HandlerAdapter是支持該controller類型的,如果找到了其中一種HandlerAdapter是支持傳過來的controller類型,那么該HandlerAdapter會調用自己的handle方法,handle方法運用Java反射機制執行controller的具體方法來獲得ModelAndView。

        5 視圖解析器ViewResolver

        SpringMVC用于處理視圖最重要的兩個接口是ViewResolver和View。ViewResolver的主要作用是把一個邏輯上的視圖名稱解析為一個真正的視圖,SpringMVC中用于把View對象呈現給客戶端的是View對象本身,而ViewResolver只是把邏輯視圖名稱解析為對象的View對象。View接口的主要作用是用于處理視圖,然后返回給客戶端。

        5.1 ViewResolver源碼分析

        1.內部資源視圖解析器InternalResourceViewResolver類,進行頁面渲染時,需要使用jstl標準標簽庫。

      public class InternalResourceViewResolver extends UrlBasedViewResolver {
      // 在進行頁面渲染時,需要使用jstl的標準標簽庫
      private static final boolean jstlPresent = ClassUtils.isPresent(
      "javax.servlet.jsp.jstl.core.Config", InternalResourceViewResolver.class.getClassLoader());

      // ...
      }

        2.InternalResourceViewResolver類的父類UrlBasedViewResolver類,根據返回頁面的名稱拼接前綴和后綴,最終形成一個完整頁面的路徑。例如:/WEB-INF/hello.jsp。

      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 = ""; // 后綴

      // ...

      protected AbstractUrlBasedView buildView(String viewName) throws Exception {
      AbstractUrlBasedView view = instantiateView();
      view.setUrl(getPrefix() + viewName + getSuffix());
      view.setAttributesMap(getAttributesMap());

      String contentType = getContentType();
      if (contentType != null) {
      view.setContentType(contentType);
      }

      String requestContextAttribute = getRequestContextAttribute();
      if (requestContextAttribute != null) {
      view.setRequestContextAttribute(requestContextAttribute);
      }

      Boolean exposePathVariables = getExposePathVariables();
      if (exposePathVariables != null) {
      view.setExposePathVariables(exposePathVariables);
      }
      Boolean exposeContextBeansAsAttributes = getExposeContextBeansAsAttributes();
      if (exposeContextBeansAsAttributes != null) {
      view.setExposeContextBeansAsAttributes(exposeContextBeansAsAttributes);
      }
      String[] exposedContextBeanNames = getExposedContextBeanNames();
      if (exposedContextBeanNames != null) {
      view.setExposedContextBeanNames(exposedContextBeanNames);
      }

      return view;
      }

      protected View applyLifecycleMethods(String viewName, AbstractUrlBasedView view) {
      ApplicationContext context = getApplicationContext();
      if (context != null) {
      Object initialized = context.getAutowireCapableBeanFactory().initializeBean(view, viewName);
      if (initialized instanceof View) {
      return (View) initialized;
      }
      }
      return view;
      }
      }

        5.2 ViewResolver解析流程

        1.將SpringMVC控制器中的返回結果封裝成一個ModelAndView對象。

        2.通過SpringMVC中的視圖解析器,使用ViewResolver對控制器返回的ModelAndView對象進行解析,將邏輯視圖轉換成物理視圖。

        3.調用View接口中的render()方法對物理視圖進行渲染。

        6 SpringMVC執行流程分析

        1.SpringMVC執行流程圖

        2.SpringMVC執行步驟

        1.客戶端瀏覽器發送請求給服務器中的前端控制器DispatcherServlet;

        2.用戶根據請求中的url路徑,通過HandlerMapping處理器映射器,找到匹配的Controller;

        3.HandlerMapping返回一個處理器執行鏈,包括N個攔截器與1個Controller的處理器。并把處理器執行鏈,返回給前端控制器DispatcherServlet;

        4.前端控制器DispatcherServlet得到處理器執行鏈之后,把Controller的Handler發送給HandlerAdapter處理器適配器;

        5.HandlerAdapter根據supports(Object handler)方法,也就是內部的匹配規則,判斷該處理器Handler是否實現了Controller接口;

        6.Handler處理器找到具體的方法handler.handleRequest(request, response),根據請求執行Controller類中的方法;

        7.Controller類執行完畢,然后返回一個ModelAndView對象給Handler處理器;

        8.Handler處理器把ModelAndView對象返回給HandlerAdapter;

        9.HandlerAdapter把ModelAndView對象返回給前端控制器DispathcerServlet;

        10.DispathcerServlet把ModelAndView對象傳遞給ViewResolver視圖解析器,根據jsp頁面的名稱拼接路;

        11.ViewResolver視圖解析器返回給DispathcerServlet前端控制器;

        12.DispathcerServlet拿到jsp路徑,由web容器對jsp頁面進行視圖渲染;

        13.Web容器把響應結果返回給瀏覽器。

        3.SpringMVC核心組件

      QQ截圖20230309160031

      好程序員公眾號

      • · 剖析行業發展趨勢
      • · 匯聚企業項目源碼

      好程序員開班動態

      More+
      • HTML5大前端 <高端班>

        開班時間:2021-04-12(深圳)

        開班盛況

        開班時間:2021-05-17(北京)

        開班盛況
      • 大數據+人工智能 <高端班>

        開班時間:2021-03-22(杭州)

        開班盛況

        開班時間:2021-04-26(北京)

        開班盛況
      • JavaEE分布式開發 <高端班>

        開班時間:2021-05-10(北京)

        開班盛況

        開班時間:2021-02-22(北京)

        開班盛況
      • Python人工智能+數據分析 <高端班>

        開班時間:2021-07-12(北京)

        預約報名

        開班時間:2020-09-21(上海)

        開班盛況
      • 云計算開發 <高端班>

        開班時間:2021-07-12(北京)

        預約報名

        開班時間:2019-07-22(北京)

        開班盛況
      IT培訓IT培訓
      在線咨詢
      IT培訓IT培訓
      試聽
      IT培訓IT培訓
      入學教程
      IT培訓IT培訓
      立即報名
      IT培訓

      Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號

      91精品新拍在线观看,91精品一区二区,91精品一区二区三区久久久久,91精品在线播放,91精品中综合久久久久婷婷