由于篇幅较长,因此分三篇进行讲解:

springmvc DispatchServlet初始化九大加载策略(一)

springmvc DispatchServlet初始化九大加载策略(二)

springmvc DispatchServlet初始化九大加载策略(三)

正文

SpringMVC 容器初始化时,

  1. protected void onRefresh(ApplicationContext context) {
  2. this.initStrategies(context);
  3. }
  4.  
  5. protected void initStrategies(ApplicationContext context) {
  6. this.initMultipartResolver(context);
  7. this.initLocaleResolver(context);
  8. this.initThemeResolver(context);
  9. this.initHandlerMappings(context);
  10. this.initHandlerAdapters(context);
  11. this.initHandlerExceptionResolvers(context);
  12. this.initRequestToViewNameTranslator(context);
  13. this.initViewResolvers(context);
  14. this.initFlashMapManager(context);
  15. }

 

1. initMultipartResolver 文件上传

源码:

  1. this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class);

MultipartResolver接口定义如下:

  1. public interface MultipartResolver {
  2. // 检查请求头是否包含文件流上传
  3. boolean isMultipart(HttpServletRequest var1);
  4.  
  5. // 文件流上传请求解析方法,解析后封装在 MultipartHttpServletRequest 对象中
  6. MultipartHttpServletRequest resolveMultipart(HttpServletRequest var1) throws MultipartException;
  7.  
  8. //
  9. void cleanupMultipart(MultipartHttpServletRequest var1);
  10. }

我们知道,相应的请求会被DispatchServlet的doDispatch方法拦截,doDispatch方法中共首先就会调用checkMultipart方法检查请求是否是包含文件流:

  1. protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
  2. if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
  3. if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
  4. this.logger.debug("...");
  5. } else if (this.hasMultipartException(request)) {
  6. this.logger.debug("...");
  7. } else {
  8. try {
  9. // 具体的文件流解析方法
  10. return this.multipartResolver.resolveMultipart(request);
  11. ...
    }  

配置例子

CommonsFileUploadSupport实现了 MultipartResolver 接口

  1. //上传文件配置
  2. @Bean(name = "multipartResolver")
  3. public CommonsFileUploadSupport commonsFileUploadSupport(){
  4. CommonsFileUploadSupport resolver = new CommonsMultipartResolver();
  5. resolver.setMaxInMemorySize(40960);
  6. resolver.setMaxUploadSize(10485760000L);
  7. return resolver;
  8. }

  

2. initLocaleResolver 国际化

DispatcherServlet.properties文件:

  1. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
  2.  
  3. org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
  4.  
  5. org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
  6. org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
  7.  
  8. org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
  9. org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
  10. org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
  11.  
  12. org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
  13. org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
  14. org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
  15.  
  16. org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
  17.  
  18. org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
  19.  
  20. org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

DispatchServlet中定义一个静态的容器初始化默认defaultStrategies方法块,如果用户没有自定义的话,就使用默认的,

  1. static {
  2. // Load default strategy implementations from properties file.
  3. // This is currently strictly internal and not meant to be customized
  4. // by application developers.
  5. try {
  6. ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
  7. defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
  8. }
  9. catch (IOException ex) {
  10. throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
  11. }
  12. }

流程:

  1. 1. this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
  2.  
  3. 2. List<T> strategies = getDefaultStrategies(context, strategyInterface)
  4.  
  5. 3. String key = strategyInterface.getName();
  6. String value = defaultStrategies.getProperty(key);
  7. // 如果value不为空, 将value转换为class类名称,然后在容器了创建对象
  8. 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根目录下, 这个文件列出了主题组成的资源:

  1. styleSheet=/themes/cool/style.css
  2. 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个:

  1. FixedThemeResolver(默认):固定格式的theme,不能在系统运行时动态更改theme。

  2. SessionThemeResolver:可在运行中通过更改cookie中的相应的key值来动态调整theme的值。

  3. CookieThemeResolver:可在运行中通过更改session中的相应的key值来动态调整theme的值

主题加载策略和initLocaleResolver类似,也是如果用户没有自定义就采用默认的方式。默认的方式为FixedThemeResolver。

一个例子:

application context .xml配置文件:

  1. <bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource">
  2. <property name="basenamePrefix" value="themes/"></property>
  3. </bean>
  4. <bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
  5. <property name="defaultThemeName" value="red" />
  6. </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初始化九大加载策略(一)的更多相关文章

  1. springmvc DispatchServlet初始化九大加载策略(三)

    7. initRequestToViewNameTranslator 请求视图名 它主要与视图解析有关,如果对ViewResolvers.ModelAndView.View等没有多大印象,可以先看第8 ...

  2. springmvc DispatchServlet初始化九大加载策略(二)

    4. initHandlerMappings 请求分发 HandlerMappings是一个List<HandlerMapping>类型数据,也就是说初始化可以存放多种Mapping,和其 ...

  3. 【死磕 Spring】----- IOC 之 Spring 统一资源加载策略

    原文出自:http://cmsblogs.com 在学 Java SE 的时候我们学习了一个标准类 java.net.URL,该类在 Java SE 中的定位为统一资源定位器(Uniform Reso ...

  4. hibernate框架学习之数据抓取(加载)策略

    Hibernate获取数据方式 lHibernate提供了多种方式获取数据 •load方法获取数据 •get方法获取数据 •Query/ Criteria对象获取数据 lHibernate获取的数据分 ...

  5. hibernate框架学习第六天:QBC、分页查询、投影、数据加载策略、二级缓存

    QBC查询 1.简单查询 Criteria c = s.createCriteria(TeacherModel.class); 2.获取查询结果 多条:list 单挑:uniqueResult 3.分 ...

  6. Hibernate 加载策略得总结

    Hibernate 加载策略得总结 加载策略(优化查询): 策略种类: 延迟加载: 等到使用的时候才会加载数据. 立即加载: 不管使用不使用,都会立刻将数据加载. 策略的应用: 类级别的加载策略. 关 ...

  7. 【sping揭秘】6、IOC容器之统一资源加载策略

    Spring中的resource 我们先看看类之间的关系 注意我们的application是间接继承了resourceloader的,也就是说我们的application其实就是一个resourcel ...

  8. ios资源加载策略

    做了好几个月的ios,大框架都是别人搭好的,自己只是实现逻辑,很是失落.慢慢开始整理学习一些概念类的东西吧,希望自己能提高点. cocos2d-x从cocos2d-2.0-x-2.0.2开始,考虑到自 ...

  9. java之hibernate之加载策略和抓取策略

    1.加载策略:指hibernate查询数据时,采用什么样的方式将数据写入内存.Hibernate中提供了两种方式来加载数据:懒加载和即时加载. 2.懒加载又称延迟加载,指使用hiberante API ...

随机推荐

  1. BEGIN-4_蓝桥杯_Fibonacci数列

    问题描述 Fibonacci数列的递推公式为:Fn=Fn-+Fn-,其中F1=F2=. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n. 输 ...

  2. java正则表达式学习

    1.简单认识正则: public class Test { public static void main(String[] args) { //简单认识正则 p("abc".ma ...

  3. 安装HBase(0.9)数据库

    基本知识: 1.hbase是一种基于列存储的数据库,也就是说它的一列的数据是存储在一个文件里面的,而传统的数据库存储都是一个文件存储多个行,这些行有不同的列,这些列的数据类型 不同. 2.基于HDFS ...

  4. IDEA在编辑时提示could not autowire

    IDEA在编辑时提示could not autowire 原创 2016年05月14日 10:53:38 28338 在开发中我再applicationContext-dao.xml中加入了mappe ...

  5. 转载 深入理解java类加载器

    1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...

  6. 查windows系统开关机记录

    https://blog.csdn.net/dufufd/article/details/53316079 者是按下"开始菜单"-"程序"-"管理工具 ...

  7. 39. 在linux下装好Tomcat要给 tomcat/bin/下面所有.sh的文件执行权限

    chmod a+x *.sh(赋予可执行的权限)

  8. Linux 配置TomCat 项目三大步骤

    一:  安装 JRE 01: 下载 server-jre 安装包 => http://www.oracle.com/technetwork/java/javase/downloads/serve ...

  9. leetcode118

    public class Solution { public IList<IList<int>> Generate(int numRows) { var list = new ...

  10. JPQL和SQL的比较

    前言 在JAVA EE中,JPQL是专门为Java 应用程序访问和导航实体实例设计的.Java Presistence Query Language(JPQL),java持久性查询语言.它是JPA规范 ...