Bootstrap

spring mvc源码学习笔记之七

我们都知道,spring mvc 有处理器适配器、处理器映射器、视图解析器等几个非常重要的核心组件,学习 spring mvc 就是学习这些组件。
本文我们就来简单看下这些组件的默认值。

下面这段代码是从 DispatcherServlet 的源码中拷贝的

static {
    // Load default strategy implementations from properties file.
    // This is currently strictly internal and not meant to be customized
    // by application developers.

    System.out.println("静态代码块先执行。加载默认的策略。 DispatcherServlet.properties 这个文件的内容非常重要  ---> " +
          " 这东西是内部用的。不是给开发者拿去自定义的。 ");

    try {
        ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
        defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
        for (Object o : defaultStrategies.keySet()) {
            System.out.println("DispatcherServlet.properties   ---> key: " + o + " 对应的 value 是 " + defaultStrategies.get(o));
        }
    }
    catch (IOException ex) {
        throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
    }
}

首先需要注意的是:这段代码是在静态代码块里边的。也就是说,这段代码在加载类的时候就会自动执行了。
然后看下这段代码干了什么事儿:从属性文件(DEFAULT_STRATEGIES_PATH 也就是 DispatcherServlet.properties )中加载默认的策略。
再说的具体点,就是在静态代码块中读取配置文件 DispatcherServlet.properties ,将其中配置的信息存到静态变量 defaultStrategies 中,供后续初始化的策略的时候使用。
啥叫默认的策略,可以简单说下,就是处理器适配器、处理器映射器、视图解析器这些组件的默认值。
接下来就是看下配置文件 DispatcherServlet.properties 的内容了,如下:

# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

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.method.annotation.RequestMappingHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	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

这个配置文件最上边有一段说明文字。翻译一下:这个文件中的内容定义了 DispatcherServlet 策略接口的默认实现类。
当在 DispatcherServlet 对应的应用上下文中没有找到对应的 bean 的时候,这里边的这些类可用作兜底,也就是作为默认值。
最后一句可以理解为,你就用这里定义的默认实现类就行了,你作为一个应用开发者,不建议你去对这些东西进行自定义。
换句话说,你要是有本领,当然可以自定义了!

  • 第一个策略组件
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

LocaleResolver 这个东西是跟国际化相关的。默认值是 AcceptHeaderLocaleResolver,也就是根据请求头 Accept-Language 来决定给你用哪国语言。

  • 第二个策略组件
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

ThemeResolver 主题解析器。

  • 第三个策略组件
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

HandlerMapping 处理器映射器。这个就非常重要了。它指定了2个值。BeanNameUrlHandlerMapping 这个我们一般很少用,想知道用法,可以百度下,比较简单。
RequestMappingHandlerMapping 这个重要,我们平时写的 @RequestMapping 就是这个东西来解析的。

  • 第四个策略组件
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

HandlerAdapter 处理器适配器。这个也非常重要。它指定了3个值。同样,3个里边最重要也是最负责的就是 RequestMappingHandlerAdapter

  • 第五个策略组件
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

HandlerExceptionResolver 处理器异常解析器。忘了说了,一直说处理器映射器、处理器适配器、处理器异常解析器,还没说啥是处理器,其实就是我们写的 controller 。在 spring mvc 中,我们写的 controller 被叫做处理器,我们写在 controller 中的方法被叫做处理器方法 HandlerMethod。这里指定了3个值,都值得点进去看看源码。

  • 第六个策略组件
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
  • 第七个策略组件
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

ViewResolver 视图解析器。默认值是 InternalResourceViewResolver ,看源码的 javadoc 就知道他是用于支持 jsp 以及 jstl 的。这也就是为啥说 spring mvc 默认支持的视图技术是 jsp 了。

  • 第八个策略组件
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

FlashMapManager 这个是跟异步请求相关的。

最后,顺便说一嘴,网上讲 spring mvc 的课程,无不是重点讲 DispatcherServlet 的,这没毛病,博主想说的是,大家可以仔细看看 DispatcherServlet 这个类的成员变量(不管是静态的还是非静态的),看完你就对 spring mvc 有个大概了解了。

;