一. 概述

  在之前的分析之中,我们看到springmvc之中使用的组件.我们在这里首先不会去说使用注解简化开发的模式,因为单单讲讲注解的使用基本任何的作用,

    稍微有一点经验的人都知道,没有注解解析,注解就仅仅只是一个标记.

  我们想要比较深刻的理解springmvc,就需要使用配置式的方式从最简单的也是最为复杂的模式下学习.


 

二 . HandlerMapping

  首先说一下HandlerMapping的作用: 核心的作用就是实现URL的映射.

  在springmvc之中,使用HandlerMapping的来描述这个行为.

我们首先看下结构:  

/**
// 实现了请求和处理器对象的映射的一个对象,我们使用HandlerMapping接口来描述.
 * Interface to be implemented by objects that define a mapping between
 * requests and handler objects.
  开发者可以实现这个接口,但是没有必要,在springmvc之中已经有了内置的几个实现.
  //比如BeanNameUrlHandlerMapping,比如DefaultAnnotationHandlerMapping
  //上面说到了这两个实现默认加载在springmvc容器之中.
 * <p>This class can be implemented by application developers, although this is not
 * necessary, as {@link org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping}
 * and {@link org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping}
 * are included in the framework. The former is the default if no
 * HandlerMapping bean is registered in the application context.
 *  HandlerMapping可以支持拦截器的映射,但是这不是必须要做的.一个HandlerMapping对象总是被包装在HandlerExecutionChain对象之中,
    同时也可以支持多个拦截器.
  前端控制器DispatcherServlet总是首先调用拦截器的前置方法,如果有多个拦截器,就按照次序依次调用,最后
  再调用拦截器的后置方法.

 * <p>HandlerMapping implementations can support mapped interceptors but do not
 * have to. A handler will always be wrapped in a {@link HandlerExecutionChain}
 * instance, optionally accompanied by some {@link HandlerInterceptor} instances.
 * The DispatcherServlet will first call each HandlerInterceptor's
 * {@code preHandle} method in the given order, finally invoking the handler
 * itself if all {@code preHandle} methods have returned {@code true}.
 *  //参数化映射是一个MVC框架最强大的能力,举个例子,我们可以按照Session状态,cookie状态或者其他的参数进行映射,
  //几乎没有任何一个MVC框架比springmvc更加灵活.
 * <p>The ability to parameterize this mapping is a powerful and unusual
 * capability of this MVC framework. For example, it is possible to write
 * a custom mapping based on session state, cookie state or many other
 * variables. No other MVC framework seems to be equally flexible.
 * //这个处理器映射器可以实现Order接口,也就拥有了优先级的概念,没有实现Order接口的实现类就按照最低等级进行处理.
 * <p>Note: Implementations can implement the {@link org.springframework.core.Ordered}
 * interface to be able to specify a sorting order and thus a priority for getting
 * applied by DispatcherServlet. Non-Ordered instances get treated as lowest priority.
 *
 
public interface HandlerMapping {

   // 我们只关注一个核心方法,那就是将一个请求转换为一个HanlerExecutionChain对象.
    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

}

三 . 标准实现

  在HandlerMapping之中,我们提到了两个实现类,他们在springmvc之中是被默认注入的.

我们首先来看BeanNameUrlHandlerMapping.

public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {

    /**
     * Checks name and aliases of the given bean for URLs, starting with "/".
     */
    @Override
    protected String[] determineUrlsForHandler(String beanName) {
        List<String> urls = new ArrayList<String>();
        if (beanName.startsWith("/")) {
            urls.add(beanName);  //使用这个HandlerMapping的时候,我们的Bean的名字需要以"/"开头,这样就知道了URL到底映射到了什么地方.
        }
        String[] aliases = getApplicationContext().getAliases(beanName);
        for (String alias : aliases) {
            if (alias.startsWith("/")) {
                urls.add(alias);
            }
        }
        return StringUtils.toStringArray(urls);
    }

}

我们再看一下DefaultAnnotationHandlerMapping

@Deprecated
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping {

我们发现这个类被废弃了.

因为之前我们使用的方式就是在一个实现特定接口的Bean的上面加上注解,但是我们希望是一个跟spring无关的Bean的实现.

  这也就是springmvc使用注解之后所采用的.


 

四 .总结

  我们现在已经知道了,HandlerMapping的核心作用就是将一个请求转换为一个HandlerExecutionChain对象.