概述
本节学习下ViewResolverComposite的功能,简单来说,该类的作用就是把多个ViewResolver视图解析器进行组装,内部使用list存储配置使用的视图解析器。
本系列文章是基于Spring5.0.5RELEASE。
源码
ViewResolverComposite实现ViewResolver接口,源码如下;
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核心代码。
实战
练习ViewResolverComposite的使用。
- 项目结构
- pom文件
通过maven构建,引入依赖的jar坐标,代码如下:
<!-- 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的组件,代码如下:
<!-- 扫描指定路径 -->
<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,代码如下:
<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>
- 处理器
编写处理器,本例使用注解,代码如下:
@Controller
public class DemoController {
@GetMapping("/viewResolverComposite")
public String viewResolverComposite(){
return "test";
}
}
- 测试
测试一:视图解析器属性order并不影响ViewResolverComposite组装使用的视图解析器顺序
根据以上配置,如果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,共同学习、共同进步,谢谢!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。