SpringMVC之源码分析--ThemeResolver(一)
概述
主题就是系统的整体样式或风格,可通过Spring MVC框架提供的主题(theme)设置应用的整体样式风格,提高用户体验。Spring MVC的主题就是一些静态资源的集合,即包括样式及图片,用来控制应用的视觉风格。
Spring MVC主题包括两部分内容,分别是Theme和ThemeResolver,下面是对两部分内容的介绍:
Theme
应用中使用Theme主题时,必须实现org.springframework.ui.context.ThemeSource
接口,web应用上下文WebApplicationContext接口继承自ThemeSource,但是实现功能委派给具体的实现,默认的委派给org.springframework.ui.context.support.ResouceBundleThemeSource
类实现,此类默认从classpath加载主题属性文件。无论是自定义ThemeSource接口的实现还是通过配置属性文件路劲的ResourceBundleThemeSource实现,都需要在Spring上下文中定义此bean,并且bean的id必须为themeSource
,Spring会自动发现并使用。
ThemeResolver
在Spring上下文中定义了Theme后,DispatcherServlet会在Spring容器中查找id为themeResolver的Bean并使用。ThemeResolver工作原理与LocaleResolver工作原理基本是一样的,它在request中查找theme主题并可以修改request的theme主题。Spring提供了如下的主题解析器:
- FixedThemeResolver 默认主题解析器,使用固定的主题,通过
defaultThemeName
属性设置,即此属性指定主题属性文件的文件名。此解析器不能动态设置主题。 - SessionThemeResolver 通过用户会话来保持主题,每个会话(session)仅需要设置一次,所有请求共享主题,但是不能两个会话共享。
- CookieThemeResolver 使用客户端cookie存储的主题
Spring提供了ThemeChangeInterceptor拦截器,通过request参数控制改变用户请求的主题。
FixedThemeResolver
默认的主题解析器(在DispatcherServlet.properties中配置默认策略),实现ThemeResolver接口,使用固定的主题,主题的名字(就是主题的属性文件名)可通过defaultThemeName
属性指定,该值默认是theme
,该类比较简单,源码如下,做下注释介绍:
public class FixedThemeResolver extends AbstractThemeResolver { // 解析主题文件名 @Override public String resolveThemeName(HttpServletRequest request) { // 返回主题文件名,默认值为theme(在父类中定义) return getDefaultThemeName(); } // 设置主题文件名,此解析器不能设置。 @Override public void setThemeName( HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName) { throw new UnsupportedOperationException("Cannot change theme - use a different theme resolution strategy"); } }
实战
- 目标
练习使用FixedThemeResolver解析器,最终效果如下:
- 项目结构
在resources下创建了主题文件夹及主题文件,webapp下创建了静态资源文件。
- 主题配置文件(myTheme.properties)
指定了一张测试图片,如下:
background=/img/wolf.jpg
- Spring配置文件
配置themeSource和themeResolver,如下:
<!-- 默认Servlet处理静态资源 --> <mvc:default-servlet-handler /> <!-- jsp视图映射与视图解析 --> <bean id="viewResolver" 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"/> </bean> <!-- 加载主题资源文件 --> <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"> <!-- 指定文件前缀,即文件所在目录,如果放在classpath下,value为空(默认从classpath下加载) --> <property name="basenamePrefix" value="theme."/> </bean> <!-- 使用FixedThemeResolver --> <bean id="themeResolver" class="org.springframework.web.servlet.theme.FixedThemeResolver"> <!-- 定义theme文件的名称 --> <property name="defaultThemeName" value="myTheme"/> </bean>
说明:
1、ResourceBundleThemeSource的属性basenamePrefix
即为主题属性文件所在目录名称,其后必须有"."或"/"。
2、FixedThemeResolver是Spring默认的解析器,再此配置是为了自定义defaultThemeName
属性值,即属性文件名称。
- 视图
本例使用jsp视图展示,代码如下:
<%@ page contentType="text/html;charset=UTF-8" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <html> <head> <title>Spring MVC Theme</title> </head> <body> <img src="<spring:theme code='background'/>" style="width: 500px;height: 300px;"> </body> </html>
- 控制器
为了测试,编写Controller控制器,跳转至jsp页面,代码如下:
@RequestMapping("/theme") public String theme(){ return "theme"; }
至此,启动程序并访问/theme地址即可看到之前的效果图。
总结
- 本例主要分析了Spring MVC对Theme整体支持,并实战了默认的ThemeResolver,后续继续分析SessionThemeResolver和CookieThemeResolver。其实此解析器与LocaleResolver的实现原理基本相同。
最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!