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个:

  1. FixedThemeResolver(默认):固定格式的theme,不能在系统运行时动态更改theme。
  2. SessionThemeResolver:可在运行中通过更改cookie中的相应的key值来动态调整theme的值。
  3. 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

原文地址:https://www.cnblogs.com/chenjunjie12321/p/9357594.html

时间: 2024-10-03 10:46:04

springmvc DispatchServlet初始化九大加载策略(一)的相关文章

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

4. initHandlerMappings 请求分发 HandlerMappings是一个List<HandlerMapping>类型数据,也就是说初始化可以存放多种Mapping,和其他几种组件加载方式一样,如果用户没有在配置文件选择 HanderMapping则会到DispatcherServlet.properties文件获取: org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.

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

7. initRequestToViewNameTranslator 请求视图名 它主要与视图解析有关,如果对ViewResolvers.ModelAndView.View等没有多大印象,可以先看第8节. RequestToViewNameTranslator主要是获取请求中的viewName,然后可以根据这个viewName获取ModelAndView对象. RequestToViewNameTranslator接口定义: public interface RequestToViewNameT

教你写Android ImageLoader框架之图片加载与加载策略

在教你写Android ImageLoader框架之初始配置与请求调度中,我们已经讲述了ImageLoader的请求配置与调度相关的设计与实现.今天我们就来深入了解图片的具体加载过程以及加载的策略(包括按顺序加载和逆序加载) ,在这其中我会分享我的一些设计决策,也欢迎大家给我提建议. 图片的加载 Loader与LoaderManager的实现 在上一篇文章教你写Android ImageLoader框架之初始配置与请求调度中,我们聊到了Loader与LoaderManager. ImageLoa

《Spring揭秘》(十) ---- ApplicationContext之统一资源加载策略

Spring的resource Spring框架内部使用Resource接口作为所有资源的抽象和接口.例如: BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("...")); ClassPathResource就是Resource的一个特定类型的实现,代表的实位于Classpath中的资源. Resource接口可以根据资源的不同类型,或者资源所处的不同场合,给出相应的具体实现: a. ByteArr

如何解决网站因图片过大加载慢的问题?

图片过大加载慢?而不是图片太多加载慢? 首先要尽可能的压缩,看用户的忍受程度.jpg 可以用很多方法压缩,png 推荐使用 TinyPNG 工具(不过正文图片,显然要选择 jpg 格式的). 然后 1,不太"在乎"用户体验的省事方法: 图片保存成渐进式的,加载会慢慢变清晰,而不是从上往下依次加载,然后放在 CDN,设置缓存之类. 2,比较"在乎"用户体验的高端方案: 判断用户的设备(主要用在移动端).网络等,分别加载不同质量的图片(例如高端 iPhone wifi

Hibernate的强制加载策略

推迟加载: 推迟加载机制是号码大全为了防止一些无谓的功用开支而提出来关键词挖掘工具的,所谓推迟加载即是当在真实需求数据的时分,才真实履行数据加载操作.在Hibernate中供给了对实体方针的推迟加载以及对调集的推迟加载,另外在Hibernate3中还供给了对特点的推迟加载.下面咱们就别离介绍这些品种的推迟加载的细节. A.实体方针的推迟加载: 假如想对实体方针运用推迟加载,有必要要在实体的映射装备文件中进行相应的装备,如下所示: ? …… 经过将class的lazy特点设置为true,来敞开实体

最新版本cocos2d&#173;2.0&#173;x&#173;2.0.2使用新资源加载策略!不再沿用-hd、-

 前段时间cocos2dx更新了最新版本cocos2d-2.0-x-2.0.2,也从这个版本开始对于资源加载与管理都改变了策略. 在之前的加载方式都是通过沿用与cocos2d-iphone一样的加载资源方式,对于图片名后添加-hd,-ipad,-ipadhd方式,当用户开启项目的高清视网膜后就可以默认寻找对应的资源.但是从cocos2d-2.0-x-2.0.2版本开始,资源加载策略不在如此了.对跨平台整合不清楚的请看cocos2dx最新2.x版本跨平台整合NDK+Xcode 最新资源加载策略

cocos creator基础-(二十四)cc.Director与资源加载策略

1: 了解creator场景切换; 2: 了解director基本的一些接口; 3: 理解资源加载的策略; cc.Director对象 1:游戏里面控制管理整个游戏全局对象,包括了场景切换等,为cc.Director对象; 2:导演对象全局只有一个cc.director,大写的为类, 小写的cc.director为全局的导演对象; 3: cc.director来获取导演对象实例; 4: 游戏中各种管理对象都可以通过cc.director获取,比如物理引擎管理,Action管理, 碰撞检测管理等;

【转】高性能Javascript--脚本的无阻塞加载策略

原文转自:http://blog.jobbole.com/78191/ Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理UI和更新Javascript运行等多个任务,而同一时间只能有一个任务被执行.Javascript运行了多长时间,那么在浏览器空闲下来响应用户交互之前的等待时间就有多长. 从基本层面说,这意味着<script>标签的出现使整个页