Spring MVC拦截器DispatcherServlet详解

来源:互联网 发布:科比身体数据 编辑:程序博客网 时间:2024/05/21 19:00

    前端控制器DispatcherServlet拦截请求之后做了什么工作呢?DispatcherServlet又是如何分派请求的呢?

    我们来根据DispatcherServlet的源代码分析一下,源代码如下:

protected void initStrategies(ApplicationContext context) {        // 初始化上传文件解析器        initMultipartResolver(context);        // 初始化本地化解析器        initLocaleResolver(context);        // 初始化主题解析器        initThemeResolver(context);        // 初始化处理器骑射器,将请求映射到处理器        initHandlerMappings(context);        // 初始化处理器适配器        initHandlerAdapters(context);        // 初始化处理器异常解析器,如果执行过程中遇到异常将交给HandlerExceptionResolver来解析        initHandlerExceptionResolvers(context);        // 初始化请求到视图名称解析器        initRequestToViewNameTranslator(context);        // 初始化视图解析器,通过ViewResolver解析逻辑视图名到具体视图实现        initViewResolvers(context);        // 初始化flash映射管理器        initFlashMapManager(context);    }

    initStrategies方法将在WebApplicationContext初始化后自动执行,自动扫描上下文的Bean,根据名称或类型匹配的机制查找自定义的组件,如果没有找到则会装配一套Spring的默认组件。在`org.springframework.web.servlet` 路径下有一个DispatcherServlet.properties配置文件,该文件指定了DispatcherServlet所使用的默认组件。

//本地化解析器org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver//主题解析器org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver//处理器映射器(共2个)org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping//处理器适配器(共3个)org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter//异常处理器(共3个)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//FlashMap映射管理器org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

    如果开发者希望使用自定义类型的组件,则只需要在Spring配置文件中配置自定义的Bean组件即可。Spring MVC如果发现上下文中有用户自定义的组件,就不会使用默认的组件。

以下是DispatcherServlet装配每种组件的细节。

本地化解析器。只允许一个实例

(1)查找名为localeResolver、类型为.LocaleResolver的Bean作为该类型组件。

(2)如果没有找到,则使用默认的实现类AcceptHeaderLocaleResolver作为该类型组件。

主题解析器。只允许一个实例。

(1)查找名为themeResolver、类型为ThemeResolver的Bean作为该类型的组件。

(2)如果没有找到,则使用默认的实现类FixedThemeResolver作为该类型组件。

处理器映射器。允许多个实例

(1)如果detectAllHandlerMappings的属性为true(默认为true),则根据类型匹配机制查找上下文以及Spring容器中所有类型为HandlerMapping的Bean,将它们作为该类型组件。

(2)如果detectAllHandlerMappings的属性为fales,则查找名为handlerMappings、类型为HandlerMapping的Bean作为该类型组件。

(3)如果通过以上两种方式都没有找到,则使用BeanNameUrlHandlerMapping实现类创建该类型的组件。

处理器适配器。允许多个实例

(1)如果detectAllHandlerAdapters属性为true(默认为true),则根据类型匹配机制查找上下文以及Spring容器中所有类型为HandlerAdapter的Bean,将它们作为该类型组件。

(2)如果detectAllHandlerAdapters的属性为false,则查找名为handlerAdapter、类型为HandlerAdapter的Bean作为该类型组件。

(3)如果通过以上两种方式都没有找到,则使用DispatcherServlet.properties配置文件中指定的三个实现类分别创建一个适配器,并将其添加到适配器列表中。

处理器异常解析器。允许多个实例

(1)如果detectAllHandlerExceptionResolvers的属性为true(默认为true),则根据类型匹配机制查找上下文以及Spring容器中所有类型为HandlerExceptionResolver的Bean,将它们作为该类型组件。

(2)如果detectAllHandlerExceptionResolver的属性为false,则查找名为handlerExceptionResolver、类型为HandlerExceptionResolver的Bean作为该类型组件。

(3)如果通过以上两种方式都没有找到,则查找DispatcherServlet.properties配置文件中定义的默认实现类,注意,该文件中没有对应处理器异常解析器的默认实现类,用户可以自定义处理器异常解析器的实现类,将之添加到DispatcherServlet.properties配置文件当中。

视图名称解析器。只允许一个实例

(1)查找名为viewNameTranslator、类型为RequestToViewNameTranslator的Bean作为该类型组件。

(2)如果没有找到,则使用默认的实现DefaultRequestToViewNameTranslator作为该类型的组件。

视图解析器。允许多个实例

(1)如果detectAllViewResolver的属性为true(默认为true),则根据类型匹配机制查找上下文以及Spring容器中所有类型为ViewResolver的Bean,将它们作为该类型组件。

(2)如果detectAllViewResolver的属性为false,则查找名为viewResolvers、类型为ViewResolver的Bean作为该类型组件。

(3)如果通过以上两种方式都没有找到,则查找DispatcherServlet.properties配置文件中定义的默认实现类InternalResolverViewResolver作为该类型的组件。

文件上传解析器。只允许一个实例

(1)查找名为muliipartResolver、类型为MuliipartResolver的Bean作为该类型组件。

(2)如果用户没有在上下文中显式定义MuliipartResolver类型的自己,则DispatcherServlet将不会加载该类型的组件。

FlashMap映射管理器。

(1)查找名为FlashMapManager、类型为SessionFlashMapManager的Bean作为该类型组件,用于管理FlashMap,即数据默认存储在HttpSession中。

    如果同一类型的组件存在多个,那么它们之间的优先级顺序如何确定呢?因为这些组件都实现了org.springFramework.core.Ordered接口,所以可以通过Order属性确定优先级的顺序,值越小的优先级越高。

0 0
原创粉丝点击