一. 概述
在之前的分析之中,我们看到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对象.