亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

alighters / 1798人閱讀

摘要:與一樣,該類(lèi)繼承抽象類(lèi),并且通過(guò)外部的屬性文件定義邏輯視圖名稱與真正的視圖對(duì)象的關(guān)系,屬性文件默認(rèn)是下的,可以通過(guò)或?qū)傩詠?lái)指定,該屬性指的是文件的基名稱,也就是說(shuō)以屬性值開(kāi)頭的屬性文件。

概述

本章再學(xué)習(xí)另外兩個(gè)ViewResolver,分別是XmlViewResolver和ResourceBundleViewResolver,從功能上說(shuō),這兩個(gè)視圖解析器都是從外部資源文件中查找視圖View對(duì)象,所以放在一章學(xué)習(xí)。

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

XmlViewResolver

該類(lèi)繼承AbstractCachingViewResolver抽象類(lèi),也就是該解析器支持視圖緩存。XmlViewResolver通過(guò)使用額外的xml配置文件來(lái)定義視圖對(duì)象,xml配置文件默認(rèn)加載/WEB-INF/views.xml,可通過(guò)location屬性參數(shù)重置加載文件。

配置文件中定義視圖對(duì)象,并指定bean名稱(id或name),該名稱與Controller處理器中返回的邏輯視圖名稱對(duì)應(yīng),從而通過(guò)url指定的路徑找到真正的視圖進(jìn)行渲染。

源碼如下:

public class XmlViewResolver extends AbstractCachingViewResolver
    implements Ordered, InitializingBean, DisposableBean {

    /** 默認(rèn)加載的視圖配置文件 */
    public static final String DEFAULT_LOCATION = "/WEB-INF/views.xml";
    /** 指定視圖配置文件路徑 */
    @Nullable
    private Resource location;
    /** 如果開(kāi)啟緩存(cacheLimit>0),bean工廠緩存在該屬性 */
    @Nullable
    private ConfigurableApplicationContext cachedFactory;
    /** 視圖解析器排序 */
    private int order = Ordered.LOWEST_PRECEDENCE;  

    ... 省略get/set方法 ...

    /** 啟動(dòng)時(shí)調(diào)用 */
    @Override
    public void afterPropertiesSet() throws BeansException {
        // 開(kāi)啟緩存(cacheLimit>0)時(shí),在應(yīng)用啟動(dòng)時(shí)創(chuàng)建bean工廠
        if (isCache()) {
            initFactory();
        }
    }
    
    /** 返回視圖名稱,在父類(lèi)AbstractCachingViewResolver的resolveViewName方法中調(diào)用 */
    @Override
    protected Object getCacheKey(String viewName, Locale locale) {
        return viewName;
    }
    
    /** 
     *根據(jù)視圖名稱加載View視圖 
     */
    @Override
    protected View loadView(String viewName, Locale locale) throws BeansException {
        // 創(chuàng)建bean工廠
        BeanFactory factory = initFactory();
        try {
            // 根據(jù)controller返回的邏輯視圖名(視圖名稱與bean名稱對(duì)應(yīng))查找視圖對(duì)象
            return factory.getBean(viewName, View.class);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // Allow for ViewResolver chaining...
            return null;
        }
    }

    /** 創(chuàng)建bean工廠 */
    protected synchronized BeanFactory initFactory() throws BeansException {
        // 如果啟用緩存,第二次直接返回
        if (this.cachedFactory != null) {
            return this.cachedFactory;
        }

        ApplicationContext applicationContext = obtainApplicationContext();

        Resource actualLocation = this.location;
        if (actualLocation == null) {
            actualLocation = applicationContext.getResource(DEFAULT_LOCATION);
        }

        // Create child ApplicationContext for views.
        GenericWebApplicationContext factory = new GenericWebApplicationContext();
        factory.setParent(applicationContext);
        factory.setServletContext(getServletContext());

        // Load XML resource with context-aware entity resolver.
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.setEnvironment(applicationContext.getEnvironment());
        reader.setEntityResolver(new ResourceEntityResolver(applicationContext));
        reader.loadBeanDefinitions(actualLocation);

        factory.refresh();
        // 啟用緩存,賦值屬性變量進(jìn)行存儲(chǔ)
        if (isCache()) {
            this.cachedFactory = factory;
        }
        return factory;
    }
    
}

以上是XmlViewResolver的核心代碼。

ResourceBundleViewResolver

與XmlViewResolver一樣,該類(lèi)繼承AbstractCachingViewResolver抽象類(lèi),并且通過(guò)外部的屬性文件定義邏輯視圖名稱與真正的視圖View對(duì)象的關(guān)系,屬性文件默認(rèn)是classpath下的views.properties,可以通過(guò)basename或basenames屬性來(lái)指定,該屬性指的是文件的基名稱,也就是說(shuō)以basename屬性值開(kāi)頭的屬性文件。

ResourceBundleViewResolver類(lèi)具有緩存功能,即把 properties 文件中定義好的屬性按照它自身的規(guī)則生成一個(gè)個(gè)的 bean 對(duì)象注冊(cè)到該 BeanFactory 中,之后會(huì)把該 BeanFactory 對(duì)象保存起來(lái),所以 ResourceBundleViewResolver 緩存的是 BeanFactory ,而不是直接的緩存從 BeanFactory 中取出的視圖 bean。

Spring 通過(guò) properties 文件生成 bean 的規(guī)則是把 properties 文件中定義的屬性名稱按最后一個(gè)點(diǎn)“ . ”進(jìn)行分割,把點(diǎn)前面的內(nèi)容當(dāng)做是 bean 名稱,點(diǎn)后面的內(nèi)容當(dāng)做是 bean 的屬性。

源碼如下:

public class ResourceBundleViewResolver extends AbstractCachingViewResolver
    implements Ordered, InitializingBean, DisposableBean {

    /** 配置文件的默認(rèn)基名稱,即以此開(kāi)頭的屬性文件,默認(rèn)從classpath路徑查找加載 */
    public static final String DEFAULT_BASENAME = "views";
    /** 支持多文件加載 */
    private String[] basenames = new String[] {DEFAULT_BASENAME};
    private ClassLoader bundleClassLoader = Thread.currentThread().getContextClassLoader();
    
    @Nullable
    private String defaultParentView;
    @Nullable
    private Locale[] localesToInitialize;

    private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered
    
    /* Locale -> BeanFactory */
    private final Map localeCache = new HashMap<>();

    /* List of ResourceBundle -> BeanFactory */
    private final Map, ConfigurableApplicationContext> bundleCache = new HashMap<>();
    
    /**********get/set**********/
    public void setBasename(String basename) {
        setBasenames(basename);
    }
    public void setBasenames(String... basenames) {
        this.basenames = basenames;
    }
    public void setBundleClassLoader(ClassLoader classLoader) {
        this.bundleClassLoader = classLoader;
    }
    protected ClassLoader getBundleClassLoader() {
        return this.bundleClassLoader;
    }
    public void setDefaultParentView(String defaultParentView) {
        this.defaultParentView = defaultParentView;
    }
    public void setLocalesToInitialize(Locale... localesToInitialize) {
        this.localesToInitialize = localesToInitialize;
    }
    public void setOrder(int order) {
        this.order = order;
    }
    @Override
    public int getOrder() {
        return this.order;
    }

    /** 啟動(dòng)時(shí)調(diào)用,創(chuàng)建初始化bean工廠 */
    @Override
    public void afterPropertiesSet() throws BeansException {
        // localesToInitialize屬性通過(guò)配置進(jìn)行設(shè)置
        if (this.localesToInitialize != null) {
            for (Locale locale : this.localesToInitialize) {
                initFactory(locale);
            }
        }
    }
    
    /** 查找視圖View,在父類(lèi)AbstractCachingViewResolver的resolverViewName方法中調(diào)用 */
    @Override
    protected View loadView(String viewName, Locale locale) throws Exception {
        // 初始化bean工廠
        BeanFactory factory = initFactory(locale);
        try {
            return factory.getBean(viewName, View.class);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // Allow for ViewResolver chaining...
            return null;
        }
    }

    protected synchronized BeanFactory initFactory(Locale locale) throws BeansException {

        // 開(kāi)啟緩存,通過(guò)cacheLimit屬性大于0控制
        if (isCache()) {
            // localeCache屬性map中緩存locale和beanFactory映射
            BeanFactory cachedFactory = this.localeCache.get(locale);
            if (cachedFactory != null) {
                return cachedFactory;
            }
        }

        // 創(chuàng)建ResourceBundle集合,支持多屬性文件
        List bundles = new LinkedList<>();
        for (String basename : this.basenames) {
            ResourceBundle bundle = getBundle(basename, locale);
            bundles.add(bundle);
        }

        // 開(kāi)啟緩存,
        if (isCache()) {
            BeanFactory cachedFactory = this.bundleCache.get(bundles);
            if (cachedFactory != null) {
                this.localeCache.put(locale, cachedFactory);
                return cachedFactory;
            }
        }

        // 創(chuàng)建視圖ApplicationContext上下文
        GenericWebApplicationContext factory = new GenericWebApplicationContext();
        factory.setParent(getApplicationContext());
        factory.setServletContext(getServletContext());

        // 從資源文件中加載bean定義
        PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(factory);
        reader.setDefaultParentBean(this.defaultParentView);
        for (ResourceBundle bundle : bundles) {
            reader.registerBeanDefinitions(bundle);
        }

        factory.refresh();

        // 設(shè)置緩存
        if (isCache()) {
            this.localeCache.put(locale, factory);
            this.bundleCache.put(bundles, factory);
        }

        return factory;
    }

    protected ResourceBundle getBundle(String basename, Locale locale) throws MissingResourceException {
        return ResourceBundle.getBundle(basename, locale, getBundleClassLoader());
    }

    @Override
    public void destroy() throws BeansException {
        for (ConfigurableApplicationContext factory : this.bundleCache.values()) {
            factory.close();
        }
        this.localeCache.clear();
        this.bundleCache.clear();
    }

}

以上是ResourceBundleViewResolver的核心代碼。

實(shí)戰(zhàn)

使用XmlViewResolver

spring mvc配置文件中配置XmlViewResolver視圖解析器,代碼如下:



    

在classpath下創(chuàng)建views.xml配置文件,代碼如下:


    

啟動(dòng)測(cè)試,可以正常進(jìn)行渲染。

使用ResourceBundleViewResolver

spring mvc配置文件中配置ResourceBundlerViewResolver視圖解析器,代碼如下:



    
    
        
            
            properties/test
            properties/views
        
    
    
    
    
    

test.properties配置如下:

// 配置視圖View
test.(class)=org.springframework.web.servlet.view.InternalResourceView
// 對(duì)應(yīng)真實(shí)視圖url
test.url=/WEB-INF/jsp/test.jsp

views.properties配置與test一樣。

啟動(dòng)測(cè)試,正常解析渲染。

總結(jié)

經(jīng)過(guò)六章的分析,學(xué)習(xí)了ViewResolver視圖解析器,回想一下,可劃分為三部分:

組合的ViewResolver,這部分是直接繼承ViewResolver接口的,不具有緩存功能,包括像ViewResolverComposite、ContentNegotiatingViewResolver等

基于url的Viewresolver,這部分包括UrlBasedViewResolver、InternalResourceViewResolver等

基于外部文件的Viewresolver,包括XmlViewResolver、ResourceBundleViewResolver

關(guān)于視圖解析器,就分析到這,希望對(duì)大家有幫助,謝謝!

最后創(chuàng)建了qq群方便大家交流,可掃描加入,同時(shí)也可加我qq:276420284,共同學(xué)習(xí)、共同進(jìn)步,謝謝!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/69689.html

相關(guān)文章

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

    摘要:概述本節(jié)學(xué)習(xí)下的功能,簡(jiǎn)單來(lái)說(shuō),該類(lèi)的作用就是把多個(gè)視圖解析器進(jìn)行組裝,內(nèi)部使用存儲(chǔ)配置使用的視圖解析器??偨Y(jié)本章介紹了類(lèi),根據(jù)測(cè)試,了解到屬性不影響中配置使用的視圖解析器順序。 概述 本節(jié)學(xué)習(xí)下ViewResolverComposite的功能,簡(jiǎn)單來(lái)說(shuō),該類(lèi)的作用就是把多個(gè)ViewResolver視圖解析器進(jìn)行組裝,內(nèi)部使用list存儲(chǔ)配置使用的視圖解析器。 本系列文章是基于Spri...

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

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

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

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

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

    摘要:概述本章繼續(xù)學(xué)習(xí)另一個(gè)實(shí)現(xiàn)類(lèi)解析器,該類(lèi)的主要作用是根據(jù)同一請(qǐng)求的某些策略,選擇對(duì)應(yīng)的進(jìn)行渲染。可以把理解為適配器,對(duì)不同類(lèi)型進(jìn)行適配。值得注意的是處理的為同一個(gè)。本系列文章是基于。實(shí)戰(zhàn)需求目標(biāo)實(shí)現(xiàn)后綴名或參數(shù)控制,顯示不同的視圖。 概述 本章繼續(xù)學(xué)習(xí)ViewResolver另一個(gè)實(shí)現(xiàn)類(lèi)ContentNegotiatingViewResolver解析器,該類(lèi)的主要作用是根據(jù)同一請(qǐng)求的某...

    jcc 評(píng)論0 收藏0
  • SpringMVC源碼分析--ViewResolver(五)

    摘要:此解析器與差不多,更改下配置文件中的類(lèi)全路徑即可。總結(jié)本章介紹了以及三個(gè)視圖解析器。這部分內(nèi)容有點(diǎn)兒多,我會(huì)盡快結(jié)束。 概述 通過(guò)上幾篇的學(xué)習(xí),我們分析了并試驗(yàn)了ViewResolverComposite、BeanNameViewResolver和ContentNegotiatingViewResolver,這三個(gè)類(lèi)都直接實(shí)現(xiàn)ViewResolver接口。Spring MVC提供了很多...

    klinson 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<