DispatcherServlet.doDispatch的mv = ha.handle(processedRequest, response, mappedHandler.getHandler());这个方法调用帮我们调用处理方法或者处理对象进行处理请求。
1.HanderAdapter.java
public interface HandlerAdapter {
//判断是否支持传入的Handler
boolean supports(Object handler);
//用来使用Handler处理请求
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
//用来获取资料的Last-Modified值
long getLastModified(HttpServletRequest request, Object handler);
}
2.常用的实现类如下图
除RequestMappingHandlerAdapter之外,HttpRequestHandlerAdapter、SimpleServletHandlerAdapter、SimpleControllerHandlerAdapter的实现非常简单;比如SimpleControllerHandlerAdapter
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return ((Controller) handler).handleRequest(request, response);
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
直接强转为Controller类型并调用其handleRequest(request,response)方法处理request请求
3.RequestMappingHandlerAdapter该类实现了InitializingBean,该方法会在bean调用BeanPostProcessor的postProcessBeforeInitialize方法之后调用init-method方法之前被调用afterPropertiesSet进行初始化操作
@Override
public void afterPropertiesSet() {
// Do this first, it may add ResponseBody advice beans
//首先执行此操作,它可能会添加ResponseBody 增强bean
initControllerAdviceCache();
if (this.argumentResolvers == null) {
//获取默认的参数解析器
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.initBinderArgumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.returnValueHandlers == null) {
//获取默认的returnValue处理器
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
4.initControllerAdviceCache();该方法获取上下文中所有的使用了@ControllerAdvice注解的bean;@ControllerAdvice从字面意思理解就是对Controller(控制器)的增强,然后以key-beanType,value-Set<Method>的方式缓存这些对控制器增强bean的有@InitBinder和@ModelAttribute注解的方法,同时也缓存那些@ControllerAdvice并且实现了RequestBodyAdvice和ResponseBodyAdvice接口的bean
private void initControllerAdviceCache() {
//获取应用上下文
if (getApplicationContext() == null) {
return;
}
if (logger.isInfoEnabled()) {
logger.info("Looking for @ControllerAdvice: " + getApplicationContext());
}
//查找带有@ControllerAdvice的bean
List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
//给这些bean排序
AnnotationAwareOrderComparator.sort(beans);
List<Object> requestResponseBodyAdviceBeans = new ArrayList<Object>();
for (ControllerAdviceBean bean : beans) {
Class<?> beanType = bean.getBeanType();
//找到bean带有@ModelAttribute注解但是没有@RequestMapping的方法 放到map里面
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
if (!attrMethods.isEmpty()) {
//放入缓存里
this.modelAttributeAdviceCache.put(bean, attrMethods);
if (logger.isInfoEnabled()) {
logger.info("Detected @ModelAttribute methods in " + bean);
}
}
//找到bean带有@InitBinder注解的方法
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
if (!binderMethods.isEmpty()) {
this.initBinderAdviceCache.put(bean, binderMethods);
if (logger.isInfoEnabled()) {
logger.info("Detected @InitBinder methods in " + bean);
}
}
//如果bean实现了RequestBodyAdvice或者ResponseBodyAdvice接口
boolean isRequestBodyAdvice = RequestBodyAdvice.class.isAssignableFrom(beanType);
boolean isResponseBodyAdvice = ResponseBodyAdvice.class.isAssignableFrom(beanType);
if (isRequestBodyAdvice || isResponseBodyAdvice) {
requestResponseBodyAdviceBeans.add(bean);
if (logger.isInfoEnabled()) {
if (isRequestBodyAdvice) {
logger.info("Detected RequestBodyAdvice bean in " + bean);
}
else {
logger.info("Detected ResponseBodyAdvice bean in " + bean);
}
}
}
}
if (!requestResponseBodyAdviceBeans.isEmpty()) {
this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
}
}
getDefaultArgumentResolvers();初始化RequestMappingHandlerAdapter的默认的HandlerMethodArgumentResolver
/**
*
* 用于在给定请求的上下文中将方法参数解析为参数值的策略接口。
*/
public interface HandlerMethodArgumentResolver {
/**
* 此解析程序是否支持给定的{@linkplain MethodParameter方法参数}。
*/
boolean supportsParameter(MethodParameter parameter);
/**
* 将给定请求的方法参数解析为 参数值
*/
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;
}
/**
* 返回要使用的参数解析器列表,包括内置解析器
* 和自定义解析器通过{@link #setCustomArgumentResolvers}提供。
*/
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
// Annotation-based argument resolution
// 基于注解的参数解析器
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new PathVariableMapMethodArgumentResolver());
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
resolvers.add(new ServletModelAttributeMethodProcessor(false));
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new SessionAttributeMethodArgumentResolver());
resolvers.add(new RequestAttributeMethodArgumentResolver());
// Type-based argument resolution
// 基于类型的参数解析器
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RedirectAttributesMethodArgumentResolver());
resolvers.add(new ModelMethodProcessor());
resolvers.add(new MapMethodProcessor());
resolvers.add(new ErrorsMethodArgumentResolver());
resolvers.add(new SessionStatusMethodArgumentResolver());
resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
// Custom arguments
//自定义解析器
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));
return resolvers;
}
getDefaultReturnValueHandlers();初始化RequestMappingHandlerAdapter的默认的HandlerMethodReturnValueHandler
/**
*
* 处理由处理程序的调用返回值的策略接口
*/
public interface HandlerMethodReturnValueHandler {
/**
* 给定的{@linkplain MethodParameter return tpye方法}是否被当前处理器支持
*/
boolean supportsReturnType(MethodParameter returnType);
/**
* 通过添加model的属性和设置视图处理返回值或者设置{@link
* ModelAndViewContainer#setRequestHandled}标识为true去表示相应已被直接处理
*
*/
void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}
/**
* 返回要使用的返回值处理程序列表,包括内置和
* 通过{@link #setReturnValueHandlers}提供的自定义处理程序。
*/
private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();
// Single-purpose return value types
handlers.add(new ModelAndViewMethodReturnValueHandler());
handlers.add(new ModelMethodProcessor());
handlers.add(new ViewMethodReturnValueHandler());
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters()));
handlers.add(new StreamingResponseBodyReturnValueHandler());
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
handlers.add(new HttpHeadersReturnValueHandler());
handlers.add(new CallableMethodReturnValueHandler());
handlers.add(new DeferredResultMethodReturnValueHandler());
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
// Annotation-based return value types
handlers.add(new ModelAttributeMethodProcessor(false));
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
// Multi-purpose return value types
handlers.add(new ViewNameMethodReturnValueHandler());
handlers.add(new MapMethodProcessor());
// Custom return value types
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
// Catch-all
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
}
else {
handlers.add(new ModelAttributeMethodProcessor(true));
}
return handlers;
}
5.RequestMappingHandlerAdapter对请求的处理方法handleInternal(HttpServletRequest request,HttpServletResponse response,HandlerMethod handlerMethod)
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
//检测当前请求,验证请求合法性和session合法性
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
// 当前是否需要在同一个session中只能同步处理请求
if (this.synchronizeOnSession) {
//获取当前请求的session对象
HttpSession session = request.getSession(false);
if (session != null) {
//获取当前session的同步锁
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
// 如果当前不存在session,则直接对HandlerMethod进行适配
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No synchronization on session demanded at all...
mav = invokeHandlerMethod(request, response, handlerMethod);
}
// 响应体不包含“Cache-Control”属性
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
// 如果当前SessionAttribute中存在配置的attributes,则为其设置过期时间。
// 这里SessionAttribute主要是通过@SessionAttribute注解生成的
// 如果咱们有sessionAttributes 根据配置的cacheSecondsForSessionAttributeHandlers时长设置
// Cache-Control属性
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
// 如果当前不存在SessionAttributes,则判断当前是否存在Cache-Control设置,
// 如果存在,则按照该设置进行response处理,如果不存在,则设置response中的
// Cache的过期时间为-1,即立即失效
prepareResponse(response);
}
}
return mav;
}
该方法通过反射调用@Controller注解的bean的@RequestMapping的方法处理请求
- a.检查请求合法性
-
/** * 检查给定的请求以获取支持的方法和必需的会话(如果有)。 * @param request current HTTP request * @throws ServletException if the request cannot be handled because a check failed * @since 4.2 */ protected final void checkRequest(HttpServletRequest request) throws ServletException { // Check whether we should support the request method. //我们不支持的请求类型抛出异常好了 String method = request.getMethod(); if (this.supportedMethods != null && !this.supportedMethods.contains(method)) { throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods); } // Check whether a session is required. //如果需要session但是request没有session 抛出异常 if (this.requireSession && request.getSession(false) == null) { throw new HttpSessionRequiredException("Pre-existing session required but none found"); } }
- b.是否需要在一个session中同步处理请求的判断,需要的话在一个session中只能按顺序处理相同的request请求
- c.调用方法处理请求invokeHandlerMethod(request,response,handlerMethod);
- c.response的"Cache-Control"属性处理