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

概述

本節學習下ViewResolverComposite的功能,簡單來講,該類的做用就是把多個ViewResolver視圖解析器進行組裝,內部使用list存儲配置使用的視圖解析器。前端

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

源碼

ViewResolverComposite實現ViewResolver接口,源碼以下;git

public class ViewResolverComposite implements ViewResolver, Ordered, InitializingBean,
    ApplicationContextAware, ServletContextAware {
    // 用於存儲使用的ViewResolver容器
    private final List<ViewResolver> viewResolvers = new ArrayList<>();
    // 支持排序
    // 此排序並不影響上面list中的順序
    private int order = Ordered.LOWEST_PRECEDENCE;

    ... ...

    /**
     *根據邏輯視圖名稱進行解析
     */
    @Override
    @Nullable
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        // 迭代配置使用的ViewResolver集合
        for (ViewResolver viewResolver : this.viewResolvers) {
            // 逐一調用不一樣的解析器進行解析
            View view = viewResolver.resolveViewName(viewName, locale);
            // 找到View即返回
            if (view != null) {
                return view;
            }
        }
        // 未找到返回null
        return null;
    }

    ... ...
}

以上是ViewResolverComposite核心代碼。github

實戰

練習ViewResolverComposite的使用。web

  • 項目結構

  • pom文件

經過maven構建,引入依賴的jar座標,代碼以下:spring

<!-- Spring MVC依賴 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>
<!-- Servlet依賴 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<!-- JSP依賴的JSTL -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
  • Spring配置文件

經過此文件配置Spring MVC的組件,代碼以下:api

<!-- 掃描指定路徑 -->
<context:component-scan base-package="com.github.dalianghe.controller"/>

<!-- 配置ViewResolverComposite視圖解析器,並裝載兩個視圖解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.ViewResolverComposite">
    <property name="viewResolvers">
        <list>
            <ref bean="internalResourceViewResolver"/>
            <ref bean="beanNameViewResolver"/>
        </list>
    </property>
    <property name="order" value="1"/>
</bean>

<!-- 本例輔助視圖解析器1 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
    <property name="order" value="3"/>
</bean>

<!-- 本例輔助視圖解析器2 -->
<bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
    <property name="order" value="2"/>
</bean>

<bean id="test" class="org.springframework.web.servlet.view.JstlView">
    <property name="url" value="/WEB-INF/jsp/test.jsp"/>
</bean>
  • 部署描述文件

配置Spring MVC核心控制器DispatcherSerlvet,代碼以下:mvc

<servlet>
    <!-- Servlet名稱,可任意定義,但必須與servlet-mapping中對應 -->
    <servlet-name>dispatcher</servlet-name>
    <!-- 指定Spring MVC核心控制類,即J2EE規範中的前端控制器(Front Controller) -->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 指定Spring MVC配置文件,默認在WEB-INF目錄下,切名字爲[servlet-name]-servlet.xml,此文件中配置web相關內容,好比:指定掃描Controller路徑、配置邏輯視圖前綴後綴、上傳文件等等 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-servlet.xml</param-value>
    </init-param>
    <!-- 此配置的值爲正整數時,表示容器啓動時初始化,即調用Servlet的init方法 -->
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<!-- 定義servlet映射 -->
<servlet-mapping>
    <!-- 與servlet中servlet-name對應 -->
    <servlet-name>dispatcher</servlet-name>
    <!-- 映射全部的url -->
    <url-pattern>/</url-pattern>
</servlet-mapping>
  • 處理器

編寫處理器,本例使用註解,代碼以下:app

@Controller
public class DemoController {
    @GetMapping("/viewResolverComposite")
    public String viewResolverComposite(){
        return "test";
    }
}
  • 測試

測試一:視圖解析器屬性order並不影響ViewResolverComposite組裝使用的視圖解析器順序jsp

根據以上配置,若是order影響的話,視圖解析應有BeanNameViewResolver進行解析,但經過測試結果並非由其進行的處理,故order不影響內部組裝順序,以下圖:

測試二:ViewResolverComposite組裝的視圖解析器順序由其存入順序影響,即如上配置屬性viewResolvers的list從上往下一次處理。

把viewResolvers的list數據順序調整一下,調整後以下:

<property name="viewResolvers">
    <list>
        <ref bean="beanNameViewResolver"/>
        <ref bean="internalResourceViewResolver"/>
    </list>
</property>

重啓再次斷點查看,以下圖:

此時處理視圖解析的變動爲BeanNameViewResolver。

測試三:測試order功能

咱們設置Spring中的ViewResolver的order屬性,以下:

<!-- 配置ViewResolverComposite視圖解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.ViewResolverComposite">
    <property name="viewResolvers">
        <list>
            <ref bean="beanNameViewResolver"/>
            <ref bean="internalResourceViewResolver"/>

        </list>
    </property>
    <property name="order" value="1"/>
</bean>

<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
    <property name="order" value="3"/>
</bean>

<bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
    <property name="order" value="2"/>
</bean>

驗證Spring加載的視圖解析器是否與咱們的順序一致,啓動時若是以下圖:

用戶請求時,結果以下圖:

由結果可知,Spring是按咱們配置的order屬性進行排序的。

總結

本章介紹了ViewResolverComposite類,根據測試,瞭解到order屬性不影響ViewResolverComposite中配置使用的視圖解析器順序。order控制Spring加載使用視圖解析器的順序。

最後建立了qq羣方便你們交流,可掃描加入,同時也可加我qq:276420284,共同窗習、共同進步,謝謝!

相關文章
相關標籤/搜索