`
234390216
  • 浏览: 10232255 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462597
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775446
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398309
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:394994
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:679961
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:530847
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1183872
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:467783
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151371
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68128
社区版块
存档分类
最新评论

SpringMVC的DispatcherServlet的默认策略

阅读更多

SpringMVC的DispatcherServlet的默认策略

在使用SpringMVC的时候,我们知道需要HandlerMapping定义请求路径与处理器之间的映射,需要HandlerAdapter来调用处理器方法并返回一个ModelAndView对象,需要ViewResolver来解析视图。这些是SpringMVC中最基本的接口。通常我们都需要在SpringMVC的配置文件中定义好需要使用的HandlerMapping、HandlerAdapter和ViewResolver,基于注解的SpringMVC配置也是类似的。所以一般我们的SpringMVC配置文件会是如下这样:

<mvc:annotation-driven/>
    <!-- 快速注册视图解析器 -->
<mvc:view-resolvers>
    <mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp"/>
</mvc:view-resolvers>

mvc命名空间是Spring提供的一个简化SpringMVC配置的命名空间,<mvc:annotation-driven/>会自动在Spring的bean容器中注册HandlerMapping接口实现RequestMappingHandlerMapping类型的bean和HandlerAdapter接口实现类RequestMappingHandlerAdapter类型的bean。<mvc:view-resolvers/>是用来快速定义ViewResolver实现的,其中<mvc:jsp/>会自动定义一个InternalResourceViewResolver类型的ViewResolver。

针对这些比较基本接口,即使我们不定义它们的实现,SpringMVC内部也给了默认的定义,它管这些叫策略。SpringMVC把这些默认策略都定义在一个叫DispatcherServlet.properties的文件中,它与DispatcherServlet在同一个包中。以下是笔者在使用的4.1.0版本中的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

 

从上面的定义中我们可以看出来,在使用SpringMVC时,即使你不定义HandlerMapping,SpringMVC默认也会给你定义一个BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping。HandlerAdapter和ViewResolver也是一样的。还有一些其它的默认策略也请参考DispatcherServlet.properties中。如果默认策略不能满足你的要求,那么我们可以在bean容器中定义我们自己对应的实现,这个时候就会应用我们自己的实现了。我们拿初始化HandlerMapping为例,来看一下DispatcherServlet的源码。

/**
 * Initialize the HandlerMappings used by this class.
 * <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace,
 * we default to BeanNameUrlHandlerMapping.
 */
private void initHandlerMappings(ApplicationContext context) {
    this.handlerMappings = null;

    if (this.detectAllHandlerMappings) {
        // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
        Map<String, HandlerMapping> matchingBeans =
                BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
        if (!matchingBeans.isEmpty()) {
            this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
            // We keep HandlerMappings in sorted order.
            OrderComparator.sort(this.handlerMappings);
        }
    }
    else {
        try {
            HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
            this.handlerMappings = Collections.singletonList(hm);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // Ignore, we'll add a default HandlerMapping later.
        }
    }

    // Ensure we have at least one HandlerMapping, by registering
    // a default HandlerMapping if no other mappings are found.
    if (this.handlerMappings == null) {
        this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
        if (logger.isDebugEnabled()) {
            logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
        }
    }
}

 

从源码中我们可以看到,SpringMVC先会从绑定的ApplicationContext中获取对应的HandlerMapping定义,如果没有取到就会调用getDefaultStrategies(context, HandlerMapping.class)从默认策略中获取。它的代码如下所示。

protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
    String key = strategyInterface.getName();
    String value = defaultStrategies.getProperty(key);
    if (value != null) {
        String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
        List<T> strategies = new ArrayList<T>(classNames.length);
        for (String className : classNames) {
            try {
                Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
                Object strategy = createDefaultStrategy(context, clazz);
                strategies.add((T) strategy);
            }
            catch (ClassNotFoundException ex) {
                throw new BeanInitializationException(
                        "Could not find DispatcherServlet's default strategy class [" + className +
                                "] for interface [" + key + "]", ex);
            }
            catch (LinkageError err) {
                throw new BeanInitializationException(
                        "Error loading DispatcherServlet's default strategy class [" + className +
                                "] for interface [" + key + "]: problem with class file or dependent class", err);
            }
        }
        return strategies;
    }
    else {
        return new LinkedList<T>();
    }
}

 

其中的defaultStrategies就是对应的DispatcherServlet.properties文件中的内容。

private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";

private static final Properties 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 'DispatcherServlet.properties': " + ex.getMessage());
    }
}

 

(注:本文是基于SpringMVC4.1.0所写)

0
0
分享到:
评论

相关推荐

    SpringMVC面试专题及答案.pdf

    SpringMVC 的控制器默认为单例模式,这意味着在多线程环境下可能存在线程安全问题。为避免这个问题,控制器内部不应包含可变状态,或者可以使用 ThreadLocal 变量来处理线程局部变量。 SpringMVC 与 Struts2 的主要...

    23道SpringMVC常见面试题.docx

    4. **多种请求资源映射策略**:SpringMVC 提供了灵活的 URL 映射策略,使得开发者能够方便地定义 URL 与控制器之间的对应关系。 5. **可扩展性**:SpringMVC 设计时考虑了扩展性,允许开发者根据需求添加自定义的...

    SpringMVC学习笔记一

    SpringMVC提供了多种映射策略,包括基于注解的映射和基于XML配置的映射。 6. **HandlerAdapter**: 由于不同的控制器可能有不同的处理方式,HandlerAdapter为DispatcherServlet提供了一种统一的方式来调用处理器。它...

    SpringMVC面试专题.pdf

    SpringMVC支持丰富的请求资源映射策略,并且是易于扩展的。 SpringMVC工作原理的核心是DispatcherServlet,它充当前端控制器的角色。当客户端发送请求到DispatcherServlet时,它首先会查询handlerMapping找到处理...

    SpringMVC面试专题1

    - **多种请求资源映射策略**:SpringMVC提供了多种方式将请求映射到相应的处理方法。 - **可扩展性**:SpringMVC的架构设计使得扩展非常方便,适应不断变化的需求。 3. **SpringMVC的工作原理** - 客户端向...

    SpringMVC访问静态资源

    然而,这种方式可能不够灵活,因为默认Servlet的配置和缓存策略可能无法满足特定应用的需求。 ### 2. 自定义静态资源路径 如果你想要自定义静态资源的路径,可以使用`&lt;mvc:resources&gt;`标签。例如,以下配置将映射`...

    SpringMVC、jQuery国际化配置

    `basename`属性用于指定资源文件的基础名称,`useCodeAsDefaultMessage`属性决定当找不到消息键时,是否使用键本身作为默认消息。 5. **LocaleResolver**:Spring提供了多种`LocaleResolver`实现,如`...

    SpringMVC配置

    开发者可以根据实际需求调整配置,如自定义更多的HandlerMapping策略、使用不同的视图技术(如Thymeleaf、Freemarker等)替换默认的JSP视图,以及集成Spring Security等安全框架增强应用的安全性。

    springmvc4.2中文文档

    对于初学者,Spring MVC提供了默认的DispatcherServlet配置,以简化开发者的配置工作。这部分会详细介绍默认配置的细节以及如何根据需要进行修改。 6. DispatcherServlet的处理流程 这部分将详细介绍...

    SpringMVC22问面试真题+答案1

    - **请求映射策略**:支持多种映射策略,使开发者可以根据需求定制。 - **易扩展性**:SpringMvc 设计得易于扩展,方便添加新的功能。 3. **SpringMVC 工作原理**: - 客户端向 DispatcherServlet 发送请求。 -...

    SpringMVC工作原理.docx

    在SpringMVC的组件中,除了Controller和View通常需要开发者根据业务需求来实现外,其他组件如DispatcherServlet、HandlerMapping、HandlerAdapter和ViewResolver通常由Spring框架提供默认实现。这些组件可以通过扩展...

    22道面试常问的SpringMVC面试题!.pdf

    SpringMVC的控制器默认是单例模式。在多线程环境下,这可能导致线程安全问题。解决方案是避免在控制器中定义实例变量,确保业务逻辑不依赖于控制器的状态。 6. **SpringMVC与Struts2的区别** - 入口点不同:...

    SpringMVC+Spring+Spring-Data-JPA整合-完整Demo

    SpringMVC的核心组件包括DispatcherServlet、Controller、ViewResolver、Model和View等。DispatcherServlet作为入口,负责请求分发;Controller处理业务逻辑;ViewResolver解析视图;Model存储数据;View负责渲染...

    SpringMVC请求流程源码分析.doc

    - `init`方法内部调用了`initStrategies`方法,该方法初始化了SpringMVC的各种策略,包括视图解析器、处理器映射器、处理器适配器等。 - 这个过程中还会创建子容器,用于管理特定于Web层的Bean。 ##### 示例代码 ...

    springmvc4DEMO

    默认情况下,Spring MVC会使用InternalResourceViewResolver,可以通过配置改变视图解析策略。 5. **模型数据绑定** @ModelAttribute注解用于将请求参数与方法参数进行绑定,使得数据可以直接传递到控制器方法中。...

    sturts2、springmvc知识点

    - 提供灵活的请求资源映射策略。 - 易于扩展和定制。 ##### 常用注解 - `@RequestMapping`: 用于映射URL到特定的类或方法。 - `@PathVariable`: 用于从URL中提取动态参数。 - `@RequestParam`: 用于从HTTP请求中...

Global site tag (gtag.js) - Google Analytics