springmvc DispatchServlet初始化九大加载策略(一)
由于篇幅较长,因此分三篇进行讲解:
springmvc DispatchServlet初始化九大加载策略(一)
springmvc DispatchServlet初始化九大加载策略(二)
springmvc DispatchServlet初始化九大加载策略(三)
正文
SpringMVC 容器初始化时,
protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
1. initMultipartResolver 文件上传
源码:
this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class);
MultipartResolver接口定义如下:
public interface MultipartResolver {
// 检查请求头是否包含文件流上传
boolean isMultipart(HttpServletRequest var1);
// 文件流上传请求解析方法,解析后封装在 MultipartHttpServletRequest 对象中
MultipartHttpServletRequest resolveMultipart(HttpServletRequest var1) throws MultipartException;
//
void cleanupMultipart(MultipartHttpServletRequest var1);
}
我们知道,相应的请求会被DispatchServlet的doDispatch方法拦截,doDispatch方法中共首先就会调用checkMultipart方法检查请求是否是包含文件流:
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
this.logger.debug("...");
} else if (this.hasMultipartException(request)) {
this.logger.debug("...");
} else {
try {
// 具体的文件流解析方法
return this.multipartResolver.resolveMultipart(request);
...
}
配置例子
CommonsFileUploadSupport实现了 MultipartResolver 接口
//上传文件配置
@Bean(name = "multipartResolver")
public CommonsFileUploadSupport commonsFileUploadSupport(){
CommonsFileUploadSupport resolver = new CommonsMultipartResolver();
resolver.setMaxInMemorySize(40960);
resolver.setMaxUploadSize(10485760000L);
return resolver;
}
2. initLocaleResolver 国际化
DispatcherServlet.properties文件:
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
DispatchServlet中定义一个静态的容器初始化默认defaultStrategies方法块,如果用户没有自定义的话,就使用默认的,
static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
}
}
流程:
1. this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); 2. List<T> strategies = getDefaultStrategies(context, strategyInterface) 3. String key = strategyInterface.getName();
String value = defaultStrategies.getProperty(key);
// 如果value不为空, 将value转换为class类名称,然后在容器了创建对象
Object strategy = this.createDefaultStrategy(context, clazz);
pringMVC国际化提供了四个国际化的实现的类AcceptHeaderLocaleResolver(默认),FixedLocaleResolver、CookieLocaleResolver和SessionLocaleResolver。
3. initThemeResolver 主题
主题的实现原理:大概就是把网站版面的css样式表和图片之类的文件和网站的程序进行解耦,程序读取theme的持久化配置,然后找到相应的css样式表和图片,配置网站版面。
要在程序中使用主题,必须设置一个org.springframework.ui.context.ThemeSource的实现类。SpringMVC IOC容器本身实现了ThemeSource,这个类只是简单的把责任代理给了一个特定的实现类,默认情况下这个代理类是:org.springframework.ui.context.support.ResourceBundleThemeSource,这个实现类可以从classpath目录下载入一个properties文件。如设置setBasenamePrefix、setDefaultEncoding等。
原理(实践)
如:SpringMVC中一套主题对应一个cool.properties文件,该文件在classpath根目录下, 这个文件列出了主题组成的资源:
styleSheet=/themes/cool/style.css
background=/themes/cool/img/coolBg.jpg
properties文件中的key是指视图文件中元素的名称,value值主题存放的位置。jsp中可以通过jsp文件可以通过spring:theme来访问这个key,然后找到value(对应的主题)。
ResourceBundleThemeSourceuses(默认的ThemeSource)的作用是根据主题名找到具体的主题,这个例子中就是找到配置文件themedemo.properties中的,默认情况下ResourceBundleThemeSource使用空的前缀名称,所以,classpath根目录下的properties文件会被载入。如果想制定位置,则可以使用basenamePrefix。
找到主题文件后,如何去解析?此时就出现了ThemeResolver。
SpringMVC中有实现主题类有3个:
FixedThemeResolver(默认):固定格式的theme,不能在系统运行时动态更改theme。
SessionThemeResolver:可在运行中通过更改cookie中的相应的key值来动态调整theme的值。
CookieThemeResolver:可在运行中通过更改session中的相应的key值来动态调整theme的值
主题加载策略和initLocaleResolver类似,也是如果用户没有自定义就采用默认的方式。默认的方式为FixedThemeResolver。
一个例子:
application context .xml配置文件:
<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource">
<property name="basenamePrefix" value="themes/"></property>
</bean>
<bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
<property name="defaultThemeName" value="red" />
</bean>
简单叙述为:ThemeResolver找到themes/目录下的所有properties中,然后SessionThemeResolver在发生改变主题请求后来解析主题。
附:如果需要根据用户请求来改变主题,则需要使用ThemeChangeInterceptor拦截器来改变主题。(拦截器有关的知识可以看本文下面的handlerMapping)
参考:
https://www.xuebuyuan.com/zh-tw/1578077.html
https://blog.csdn.net/u012410733/article/details/52915063
springmvc DispatchServlet初始化九大加载策略(一)的更多相关文章
- springmvc DispatchServlet初始化九大加载策略(三)
7. initRequestToViewNameTranslator 请求视图名 它主要与视图解析有关,如果对ViewResolvers.ModelAndView.View等没有多大印象,可以先看第8 ...
- springmvc DispatchServlet初始化九大加载策略(二)
4. initHandlerMappings 请求分发 HandlerMappings是一个List<HandlerMapping>类型数据,也就是说初始化可以存放多种Mapping,和其 ...
- 【死磕 Spring】----- IOC 之 Spring 统一资源加载策略
原文出自:http://cmsblogs.com 在学 Java SE 的时候我们学习了一个标准类 java.net.URL,该类在 Java SE 中的定位为统一资源定位器(Uniform Reso ...
- hibernate框架学习之数据抓取(加载)策略
Hibernate获取数据方式 lHibernate提供了多种方式获取数据 •load方法获取数据 •get方法获取数据 •Query/ Criteria对象获取数据 lHibernate获取的数据分 ...
- hibernate框架学习第六天:QBC、分页查询、投影、数据加载策略、二级缓存
QBC查询 1.简单查询 Criteria c = s.createCriteria(TeacherModel.class); 2.获取查询结果 多条:list 单挑:uniqueResult 3.分 ...
- Hibernate 加载策略得总结
Hibernate 加载策略得总结 加载策略(优化查询): 策略种类: 延迟加载: 等到使用的时候才会加载数据. 立即加载: 不管使用不使用,都会立刻将数据加载. 策略的应用: 类级别的加载策略. 关 ...
- 【sping揭秘】6、IOC容器之统一资源加载策略
Spring中的resource 我们先看看类之间的关系 注意我们的application是间接继承了resourceloader的,也就是说我们的application其实就是一个resourcel ...
- ios资源加载策略
做了好几个月的ios,大框架都是别人搭好的,自己只是实现逻辑,很是失落.慢慢开始整理学习一些概念类的东西吧,希望自己能提高点. cocos2d-x从cocos2d-2.0-x-2.0.2开始,考虑到自 ...
- java之hibernate之加载策略和抓取策略
1.加载策略:指hibernate查询数据时,采用什么样的方式将数据写入内存.Hibernate中提供了两种方式来加载数据:懒加载和即时加载. 2.懒加载又称延迟加载,指使用hiberante API ...
随机推荐
- SpringBoot中实现依赖注入功能
本文转载自:https://blog.csdn.net/linzhiqiang0316/article/details/52639888 今天给大家介绍一下SpringBoot中是如何实现依赖注入的功 ...
- 云-AWS-百科:AWS
ylbtech-云-AWS-百科:AWS Amazon Web Services AWS是亚马逊公司旗下云计算服务平台,为全世界范围内的客户提供云解决方案.AWS面向用户提供包括弹性计算.存储.数据库 ...
- python 使用selenium和requests爬取页面数据
目的:获取某网站某用户下市场大于1000秒的视频信息 1.本想通过接口获得结果,但是使用post发送信息到接口,提示服务端错误. 2.通过requests获取页面结果,使用html解析工具,发现麻烦而 ...
- MySQL 二进制文件恢复
先不说话 先来一段代码块 mysql> show variables like 'autocommit'; +---------------+-------+ | Variable_name ...
- TensorFlow函数:tf.FIFOQueue队列
转载:https://blog.csdn.net/akadiao/article/details/78552037 tf.FIFOQueue tf.FIFOQueue继承基类QueueBase. Qu ...
- Chrome 鼠标左键-新标签打开
改chrome设置 1.打开google搜索主页2.打开右下角Settings选项->Search Settings3.找到where results open选项4.把Open each se ...
- MySQL 安装方法
所有平台的Mysql下载地址为: MySQL 下载. 挑选你需要的 MySQL Community Server 版本及对应的平台. Linux/UNIX上安装Mysql Linux平台上推荐使用RP ...
- VueCli
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,Vue CLI 致力于将 Vue 生态中的工具基础标准化.它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写 ...
- DOM实战-js todo
1.需求: 实现一个如下页面: 最上面是输入框,后面是add按钮,输入文本点击add按钮,在下面就会出现一行,下面出现的每行最前面是两个按钮,然后后面是todo(要做的事) 第一个按钮是完成按钮,第二 ...
- 手贱!使用django,在数据库直接删除了表
莫名其妙的错误. 删除了migreation文件,并且更换了数据库. 1.直接makemigrations + migrate error: no change ?? WTF 2.makemi ...