SpringMVC之源码分析--ViewResolver(三)
概述
本节学习下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,共同学习、共同进步,谢谢!