国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SpringMVC之源碼分析--ViewResolver(五)

klinson / 2214人閱讀

摘要:此解析器與差不多,更改下配置文件中的類全路徑即可。總結本章介紹了以及三個視圖解析器。這部分內容有點兒多,我會盡快結束。

概述

通過上幾篇的學習,我們分析了并試驗了ViewResolverComposite、BeanNameViewResolver和ContentNegotiatingViewResolver,這三個類都直接實現ViewResolver接口。Spring MVC提供了很多的ViewResolver實現,本章我們繼續分析比較常用的幾個視圖解析器。

本系列文章是基于Spring5.0.5RELEASE。

AbstractCachingViewResolver

AbstractCachingViewResolver實現ViewResolver接口的抽象類,從類名可知,該類具有緩存功能,即緩存解析過的視圖View對象,后續需要視圖解析時,會先從緩存中查找,如果找到對應的視圖就直接返回,如果未找到就創建一個視圖對象放入緩存Map中,并返回創建對象。從其實現原理上來看,此類視圖解析器的性能是最佳的。

public abstract class AbstractCachingViewResolver extends WebApplicationObjectSupport implements ViewResolver {
    /** 緩存視圖map的初始大小 */
    public static final int DEFAULT_CACHE_LIMIT = 1024;
    
    /** 最大緩存數量 */
    private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;

    /** 解析過的View緩存容器,key是邏輯視圖名,value是視圖View對象 */
    private final Map viewAccessCache = new ConcurrentHashMap<>(DEFAULT_CACHE_LIMIT);

    /** 存儲所有創建過的視圖,本容器里的內容大于等于viewAccessCache中的內容
        key是邏輯視圖名,value是視圖View對象 */
    private final Map viewCreationCache =
        new LinkedHashMap(DEFAULT_CACHE_LIMIT, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                // 本容器內數量大于緩存數量時,移除最老的對象
                if (size() > getCacheLimit()) {
                    // 移除緩存容器中最老的View對象
                    viewAccessCache.remove(eldest.getKey());
                    return true;
                }
                else {
                    return false;
                }
            }
        };

    /** 實現ViewResolver接口resolveViewName方法 */
    @Override
    @Nullable
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        // 緩存開關(默認開啟)。通過屬性cacheLimit的值控制,大于0開啟緩存,小于0關閉緩存
        if (!isCache()) {
            return createView(viewName, locale);
        }
        else {
            // 獲取邏輯視圖名稱
            Object cacheKey = getCacheKey(viewName, locale);
            // 從緩存容器中查找緩存過的視圖對象
            View view = this.viewAccessCache.get(cacheKey);
            // 緩存中未找到
            if (view == null) {
                synchronized (this.viewCreationCache) {
                    // 從創建過的視圖容器中查找
                    view = this.viewCreationCache.get(cacheKey);
                    if (view == null) {
                        // 調用子類創建視圖View對象
                        view = createView(viewName, locale);
                        if (view == null && this.cacheUnresolved) {
                            view = UNRESOLVED_VIEW;
                        }
                        if (view != null) {
                            // 放入已訪問緩存容器
                            this.viewAccessCache.put(cacheKey, view);
                            // 放入已創建視圖容器
                            this.viewCreationCache.put(cacheKey, view);
                            if (logger.isTraceEnabled()) {
                                logger.trace("Cached view [" + cacheKey + "]");
                            }
                        }
                    }
                }
            }
            // 返回View對象
            return (view != UNRESOLVED_VIEW ? view : null);
        }
    }
    ... ...
}

以上是AbstractCachingViewResolver的核心代碼。簡單說,本類就是實現了視圖解析的緩存功能。

UrlBasedViewResolver

該類是ViewResolver接口的一種實現,并繼承了AbstractCachingViewResolver抽象類,通過指定prefix前綴和suffix后綴,然后拼接邏輯視圖名稱加上前綴和后綴的方式確定視圖URL。

UrlBasedViewResolver支持返回視圖名稱中包括redirect:前綴,以支持在客戶端的跳轉。比如當訪問一個url"/demo",該url對應的handler返回的邏輯視圖名為"redirect:/demo1",URLBasedViewResolver在創建視圖時(createView方法中),判斷邏輯視圖名稱的前綴是"redirect:"開頭,接著裁剪掉"redirect:"前綴后,創建RedirectView對象,RedirectView對象將把請求返回的模型數據組合成查詢參數形式拼接到redirect的URL后面,然后調用 HttpServletResponse 對象的 sendRedirect 方法進行重定向。(稍后我們實踐驗證)

同樣的,URLBasedViewResolver還支持"forword:"前綴,然后封裝成一個 InternalResourceView 對象,服務器端利用 RequestDispatcher 的 forword 方式跳轉到指定的地址。

說了這么多,我們看下源碼是如何實現的,如下:

public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {
    ... ...
    
    /** 創建View實例 */
    @Override
    protected View createView(String viewName, Locale locale) throws Exception {
        // If this resolver is not supposed to handle the given view,
        // return null to pass on to the next resolver in the chain.
        if (!canHandle(viewName, locale)) {
            return null;
        }
        // 處理redirect請求
        if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
            // 去掉redirect:前綴
            String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
            // 根據redirectUrl創建RedirectView實例
            RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
            String[] hosts = getRedirectHosts();
            if (hosts != null) {
                view.setHosts(hosts);
            }
            return applyLifecycleMethods(viewName, view);
        }
        // 處理forward請求
        if (viewName.startsWith(FORWARD_URL_PREFIX)) {
            去掉forward:前綴
            String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
            return new InternalResourceView(forwardUrl);
        }
        // Else fall back to superclass implementation: calling loadView.
        // 處理普通view(除redirect/forward)
        // 調用父類createView方法,然后通過模板方法再調回本例的loadView方法
        return super.createView(viewName, locale);
    }

    @Override
    protected View loadView(String viewName, Locale locale) throws Exception {
        AbstractUrlBasedView view = buildView(viewName);
        View result = applyLifecycleMethods(viewName, view);
        return (view.checkResource(locale) ? result : null);
    }

    ... ...
}
InternalResourceViewResolver

InternalResourceViewResolver繼承UrlBasedViewResolver,故UrlBaseViewResolver具有的功能,InternalResourceViewResolver同樣具備,在實際項目中也是使用最廣泛的一種視圖解析器。InternalResourceViewResolver會把返回的視圖對象解析為InternalResourceView 對象,InternalResourceView 會把 Controller 處理器方法返回的模型屬性都存放到對應的 request 屬性中,然后通過 RequestDispatcher 在服務器端把請求 forword 重定向到目標 URL。代碼如下:

public class InternalResourceViewResolver extends UrlBasedViewResolver {

    ... ...
    /** 構造函數 */
    public InternalResourceViewResolver() {
        // 獲取InternalResourceView
        Class viewClass = requiredViewClass();
        if (InternalResourceView.class == viewClass && jstlPresent) {
            viewClass = JstlView.class;
        }
        setViewClass(viewClass);
    }

    @Override
    protected Class requiredViewClass() {
        return InternalResourceView.class;
    }

    ... ...

}

其他功能都與UrlBasedViewResolver一樣。

實戰練習

UrlBaseViewResolver

Spring配置文件代碼如下:


    
    
    
    
    
    
    

Controller代碼如下:

@Controller
public class DemoController {

    /** 測試redirect */
    @GetMapping("/redirect")
    public String redirect(ModelMap modelMap){
        modelMap.put("name","daliang");
        modelMap.put("pass","111");
        return "redirect:/demo";
    }
    /** 測試forward */
    @GetMapping("/forward")
    public String forward(ModelMap modelMap){
        modelMap.put("name","daliang");
        modelMap.put("pass","111");
        return "forward:/demo";
    }

    @GetMapping("/demo")
    public String demo(){
        return "test";
    }

}

啟動應用,在瀏覽器地址欄輸入http://localhost:8088/redirect,回車后如下:

可見參數拼接到了url后面。

InternalResourceViewResolver

此解析器與UrlBasedViewResolver差不多,更改下配置文件中的類全路徑即可。

總結

本章介紹了AbstractCachingViewResolver、UrlBasedViewResolver以及InternalResourceViewResolver三個視圖解析器。這部分內容有點兒多,我會盡快結束。希望能幫到大家,謝謝!

最后創建了qq群方便大家交流,可掃描加入,同時也可加我qq:276420284,共同學習、共同進步,謝謝!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69672.html

相關文章

  • SpringMVC源碼分析--ViewResolver(三)

    摘要:概述本節學習下的功能,簡單來說,該類的作用就是把多個視圖解析器進行組裝,內部使用存儲配置使用的視圖解析器。總結本章介紹了類,根據測試,了解到屬性不影響中配置使用的視圖解析器順序。 概述 本節學習下ViewResolverComposite的功能,簡單來說,該類的作用就是把多個ViewResolver視圖解析器進行組裝,內部使用list存儲配置使用的視圖解析器。 本系列文章是基于Spri...

    fox_soyoung 評論0 收藏0
  • SpringMVC源碼分析--ViewResolver(二)

    摘要:概述上篇學習了視圖解析器作用及處理流程,為我們提供了豐富的視圖解析器見下圖本系列文章是基于。該視圖解析器是根據處理器返回的邏輯視圖名稱,在應用上下文中查找該名稱的視圖對象視圖對象就是的對象。 概述 上篇學習了Spring MVC ViewResolver視圖解析器作用及處理流程,Spring為我們提供了豐富的視圖解析器(見下圖):showImg(https://segmentfault...

    jas0n 評論0 收藏0
  • SpringMVC源碼分析--ViewResolver(一)

    摘要:概述本章開始進入另一重要的組件,即視圖組件,處理視圖組件使用兩個主要的接口是和。接口的作用是用于處理視圖進行渲染。延用之前的介紹流程,本章分兩部分進行闡述啟動初始化和請求處理。 概述 本章開始進入另一重要的組件,即視圖組件,Spring MVC處理視圖組件使用兩個主要的接口是ViewResolver和View。根據名稱可知,ViewResolver即視圖解析器,其作用是把邏輯視圖名稱解...

    pf_miles 評論0 收藏0
  • SpringMVC源碼分析--ViewResolver(四)

    摘要:概述本章繼續學習另一個實現類解析器,該類的主要作用是根據同一請求的某些策略,選擇對應的進行渲染。可以把理解為適配器,對不同類型進行適配。值得注意的是處理的為同一個。本系列文章是基于。實戰需求目標實現后綴名或參數控制,顯示不同的視圖。 概述 本章繼續學習ViewResolver另一個實現類ContentNegotiatingViewResolver解析器,該類的主要作用是根據同一請求的某...

    jcc 評論0 收藏0
  • SpringMVC源碼分析--ViewResolver(六)

    摘要:與一樣,該類繼承抽象類,并且通過外部的屬性文件定義邏輯視圖名稱與真正的視圖對象的關系,屬性文件默認是下的,可以通過或屬性來指定,該屬性指的是文件的基名稱,也就是說以屬性值開頭的屬性文件。 概述 本章再學習另外兩個ViewResolver,分別是XmlViewResolver和ResourceBundleViewResolver,從功能上說,這兩個視圖解析器都是從外部資源文件中查找視圖V...

    alighters 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<