springmvc DispatchServlet初始化九大加载策略(二)
4. initHandlerMappings 请求分发
HandlerMappings是一个List<HandlerMapping>类型数据,也就是说初始化可以存放多种Mapping,和其他几种组件加载方式一样,如果用户没有在配置文件选择 HanderMapping则会到DispatcherServlet.properties文件获取:
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
可知默认情况下初始化的BeanNameUrlHandlerMapping与DefaultAnnotationHandlerMapping这两种Mapping:
DefaultAnnotationHandlerMapping
(spring3.1以后已经过时)目前使用RequestMappingHandlerMapping来代替,用于注解@Controller,@RequestMapping来定义controller,主要作用是将Controller的注解值(类路径及方法路径)与Controller实例映射起来。
BeanNameUrlHandlerMapping
通过配置文件,把一个URL映射到Controller
HandlerMapping家族有两个分支,分别是AbstractUrlHandlerMapping和AbstractHandlerMethodMapping,它们又统一继承于AbstractHandlerMapping,他们的作用简单描述如下:
- AbstractUrlHandlerMapping: 通过匹配URL,将URL与handler联系起来
- AbstractHandlerMethodMapping: 普遍用于@requestMaping,匹配内容将它的Method作为handler
HanderMapping接口只有一个方法getHandler(request),它的作用是获取HandlerExecutionChain,HandlerExecutionChain对象封装了一个handler处理对象和一些interceptors,也就是说每一次请求要执行hander与这些拦截器相关的逻辑。关于Handler与Interceptor 拦截器的具体知识可以参考《浅探SpringMVC中HandlerExecutionChain之handler、interceptor》
5. initHandlerAdapters 请求handler处理器
与HandlerMappings一样,HandlerAdapters是一个List类型数据,默认的HandlerAdapters为SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter,如下:
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
SpringMVC 中通过Handler来找到支持它的HandlerAdapter,找到Handler对应的HandlerAdapter后,处理这个Hander(也就是处理这个请求)。其中AnnotationMethodHandlerAdapter已经被废除。
“HandlerAdapter字面上的意思就是处理适配器,它的作用用一句话概括就是调用具体的方法对用户发来的请求来进行处理。当handlerMapping获取到执行请求的controller时,DispatcherServlte会根据controller对应的controller类型来调用相应的HandlerAdapter来进行处理。” -- 《SpringMVC之HandlerAdapter解析》
HandlerAdapter 接口中的3个方法如下:
// 当前 HandlerAdapter 是否支持这个 Handler boolean supports(Object handler); // 处理Handler请求,并返回一个视图对象ModelAndView ModelAndView handle(HttpServletRequest req, HttpServletResponse res, Object handler); // 获取最后修改时间 long getLastModified(HttpServletRequest request, Object handler);
spingmvc 4.3中实现了HandlerAdapter接口的有6个类,其中AnnotationMethodHandlerAdapter已经废除,剩下5个:
- AbstractHandlerMethodAdapter -- (方便扩展,)
- RequestMappingHandlerAdapter -- 可以执行是 HadnlerMethod 类型的 Handler
- HttpRequestHandlerAdapter -- 可以执行 HttpRequestHandler 类型的 Handler
- SimpleControllerHandlerAdapter -- 可以执行 Controller 类型的 Handler
- SimpleServletHandlerAdapter -- 可以执行 Servlet 类型的 Handler
一个误区: 由于在项目中常见也是常有的处理器用的是配置的方式来做的,因此很容易以为Controller接口就是所有的处理器的接口,眼里就只有Controller了。处理器根本就不只有Controller这一种。还有HttpRequestHandler,Servlet等处理器。
RequestMappingHandlerMapping 会把Controller里面带有@RequestMapping注解的方法都加到一个容器里面,然后RequestMappingHandlerAdapter根据里面的自定义配置可以对经过这些方法的请求的数据做一些额外的处理。
SimpleControllerHanderAdapter 主要用于用于自定Controller接口的handleRequest,我们还记得刚开始学习Controller时候,自定Controller要么继承AbstractController,要么implements Controller接口。
HttpRequestHandlerAdapter 处理HttpRequestHandler类型的Handler,如: SpringMVC中请求经过dispatcherServlet时并不能找到资源,当设置了默认的servlet时候,就会被DefaultServletHttpRequestHandler处理。
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping>
SimpleServletHandlerAdapter (待补充)
6. initHandlerExceptionResolvers 请求异常
官方文档大致描述:
Interface to be implemented by objects that can resolve exceptions thrown during handler mapping or execution, in the typical case to error views. Implementors are typically registered as beans in the application context. Error views are analogous to JSP error pages but can be used with any kind of exception including any checked exception, with potentially fine-grained mappings for specific handlers.
由对象实现的接口,可以解析在处理程序映射或执行期间抛出的异常,尤其是在视图解析是发生的异常错误。 HandlerExceptionResolver实现者通常在应用程序上下文中注册为bean。 错误视图类似于JSP错误页面,但可以与任何类型的异常一起使用,包括任何已检查的异常,以及特定处理程序的潜在细粒度映射。