- 1、HandlerAdapter是一个接口,是具体使用Handler来干活的;
- 2、方法:
<1>supports:传入一个Object类型的handler判断是否支持处理该handler;
<2>handle:具体使用handler处理请求的过程,返回类型为ModelAndView;
<3>getLastModified:获取资源上一次更改的时间;
- 3、5个实现类:
AbstractHandlerMethodAdapter、HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter、AnnotationHandlerMethodAdapter
SimpleServletHandlerAdapter
- 4、HandlerAdapter采用了适配器模式:
以SimpleControllerHandlerAdapter为例:
源角色(adaptee):等待被适配的角色,为Controller接口;
适配器(具体类adapter):SimpleControllerHandlerAdapter;
目标角色(接口):最终想要适配成的角色,为HandlerAdapteer接口;
通俗的讲:Controller的handleRequest方法才能正确处理请求,而此方法不满足调用的要求(即不直接调用),而是通过SimpleControllerHandlerAdapter类的handle方法间接的调用;
AbstractHandlerMethodAdapter:
- 1、重写了HandlerAdapter的三个方法;
<1>supports调用supportsInternal模板方法;
<2>handle调用了handleInternal模板方法;
<3>getLastModified调用了getLastModifiedInternal模板方法;
- 2、实现了Order接口,有先后顺序之分;
- 3、继承了WebContentGenerator
- 4、子类为RequestMappingHandlerAdapter;
RequestMappingHandlerAdapter:
- 1、实现InitializingBean,使用afterPropertiesSet来初始化参数;
<1>Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache,缓存由@ControllerAdvice注解的类里边注解了@ModelAttribute却没有注解@RequestMapping的方法;
<2>Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache,缓存由@ControllerAdvice注解的类中注解了@InitBinder的方法;
<3>List<Object> requestResponseBodyAdvice,缓存实现了ResponseBodyAdvice和RequestBodyAdvice接口的类;
<4>HandlerMethodArgumentResolverComposite argumentResolvers,缓存参数解析器,通过getDefaultArgumentResolvers方法获取;包含26个默认的参数解析器,如果有自定义的,也会添加进来;
<5>HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;通过getDefaultInitBinderArgumentResolvers方法获取,包含12个默认的参数解析器,如果有自定义的,也会添加进来;
<6>HandlerMethodReturnValueHandlerComposite returnValueHandlers,通过getDefaultReturnValueHandlers方法获取,包含15个默认的返回值处理器,如果有自定义的,将会加进来,其中:若Lsit<ModelAndViewResolver>容器不为空,则15个中有一个是ModelAndViewResolverMethodReturnValueHandler,否则为ModelAttributeMethodProcessor;
- 2、getDefaultArgumentResolvers:
获取argumentResolvers,这里的解析器份为4类,按顺序依次为:基于注解的参数解析器、基于类型的参数解析器、自定义的解析器、解析所有的参数解析器;
注意:在解析器被使用时是严格按照加入的顺序进行解析的!!,例如自定义了一个解析@RequestParam的解析器,是不会生效的,因为在轮到此自定义解析器解析时,被@RequestParam注解的参数已经被springMVC的RequestParamMapMthodArgumentResolver解析完了;
- 3、handleInternal方法;(springMVC版本为5.0.4-RELEASE)
<1>checkRequest:
①如果supportedMethods不为null,则检查当前Method是否在其中,不在则抛异常HttpRequestMethodNotSupportedException;
②如果requireSession为true,并且request.getSession(false) == null,则抛异常HttpSessionRequiredException;
③supportedMethods的初始化:在RequestMappingHandlerAdapter的父类WebContentGenerator构造方法
WebContentGenerator(boolean restrictDefaultSupportedMethods)中如果传入true,则只支持Get、Post、Head三种请求方式;
<2>invokeHandlerMethod:
synchronizeOnSession值为true则开启session同步,以同步的方式调用invokeHandlerMethod,否则不以同步的方式调用;