这个接口有3个方法supports handler getLastModified
HandlerAdapter是具体通过使用Handler的来干活的。
每个HandlerAdapter封装了一种Hanlder的具体使用方法。
HandlerAdapter的子类有
AbstractMethodHandler RequestMappingHandlerAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
SimpleServletHandlerAdapter
后3个格式形式固定,只调用固定的方法就可以了
RequestMappingHandlerAdapter处理的Handler可以是任意方法。
而调用采用是反射的方法 但是参数解析麻烦
首先HttpHandlerAdapter
public class HttpRequestHandlerAdapter implements HandlerAdapter {
//判断此Handler是不是HttpRequestHandler
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
//调用HttpRequestHandler的handlerRequest
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
//同样的调用httphandler的方法
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
SimpleServletHandlerAdapter
public class SimpleServletHandlerAdapter implements HandlerAdapter {
//判断是否是servlet
@Override
public boolean supports(Object handler) {
return (handler instanceof Servlet);
}
//调用service方法
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((Servlet) handler).service(request, response);
return null;
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
return -1;
}
}
SimpleControllerHandlerAdapter
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
//判断是否是Controller
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
//调用handlerRequest方法
@Override
@Nullable
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;
}
}
发现supports是判断是否符合指定类型
handler不同的adapter调用不同的方法
http和controller调用handleRequest,而servlet调用service
我们知道AbstractHandlerMethodAdapter的3个方法调用子类的模板方法
还是上源码吧
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
private int order = Ordered.LOWEST_PRECEDENCE;
public AbstractHandlerMethodAdapter() {
// no restriction of HTTP methods by default
super(false);
}
/**
* Specify the order value for this HandlerAdapter bean.
* <p>Default value is {@code Integer.MAX_VALUE}, meaning that it's non-ordered.
* @see org.springframework.core.Ordered#getOrder()
*/
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
/**
* This implementation expects the handler to be an {@link HandlerMethod}.
* @param handler the handler instance to check
* @return whether or not this adapter can adapt the given handler
*/
@Override
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
/**
* Given a handler method, return whether or not this adapter can support it.
* @param handlerMethod the handler method to check
* @return whether or not this adapter can adapt the given method
*/
protected abstract boolean supportsInternal(HandlerMethod handlerMethod);
/**
* This implementation expects the handler to be an {@link HandlerMethod}.
*/
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
/**
* Use the given handler method to handle the request.
* @param request current HTTP request
* @param response current HTTP response
* @param handlerMethod handler method to use. This object must have previously been passed to the
* {@link #supportsInternal(HandlerMethod)} this interface, which must have returned {@code true}.
* @return ModelAndView object with the name of the view and the required model data,
* or {@code null} if the request has been handled directly
* @throws Exception in case of errors
*/
@Nullable
protected abstract ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;
/**
* This implementation expects the handler to be an {@link HandlerMethod}.
*/
@Override
public final long getLastModified(HttpServletRequest request, Object handler) {
return getLastModifiedInternal(request, (HandlerMethod) handler);
}
/**
* Same contract as for {@link javax.servlet.http.HttpServlet#getLastModified(HttpServletRequest)}.
* @param request current HTTP request
* @param handlerMethod handler method to use
* @return the lastModified value for the given handler
*/
protected abstract long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod);
但是在supports方法中必须保证handler是HandlerMethod类型 ,另外实现了Order接口,可以在配置时设置顺序。
然后分析所有组件中最复杂的RequestMappingHandlerAdapter
它的supportsInternal直接返回true 不增加判断条件
/**
* Always return {@code true} since any method argument and return value
* type will be processed in some way. A method argument not recognized
* by any HandlerMethodArgumentResolver is interpreted as a request parameter
* if it is a simple type, or as a model attribute otherwise. A return value
* not recognized by any HandlerMethodReturnValueHandler will be interpreted
* as a model attribute.
*/
@Override
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
没啥可说的
/**
* This implementation always returns -1. An {@code @RequestMapping} method can
* calculate the lastModified value, call {@link WebRequest#checkNotModified(long)},
* and return {@code null} if the result of that call is {@code true}.
*/
@Override
protected long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod) {
return -1;
}
模板方法直接返回-1,这些都简单
最主要是handleInternal
大致分为3步
1. 备好处理数据
2. 使用处理器处理请求
3. 处理返回值,将不同类型值统一生成ModelAndView类型。
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No synchronization on session demanded at all...
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
先分析第一步
首先要理解准备参数的话
需要思考那些参数需要绑定:
根据方法确定 处理器 注解了ModelAttribute InitBinder的方法
参数值得来源:
6个来源
request相关参数 url post参数 请求头
cookie参数
session参数
设置到FlashMap中的参数 用于redirect参数传递
sessionAttributes传递的参数
modelAttributes设置的参数
具体绑定的方法
参数的解析是通过HandlerMethodArgumentResolver完成
WebDataBinder @InitBinder来初始化 使用同一套ArguementResolver来解析。
由于它的组件过多 首先有必要进行自身分析结构
首先看一看它有哪些组件
(一)adapter的创建过程
它的创建是在afterPropertiesSet方法中实现
内容初始化argumentResolvers,
6个属性
@Override
public void afterPropertiesSet() {
// Do this first, it may add ResponseBody advice beans
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) {
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
argumentResolvers
initBinderArguementResolvers
returnValueHandlers
modelAttributeAdviceCache initBinderAdviceCache
responseBodyAdvice
adapter的使用过程
handleInternal主要两句代码 checkAndPrepare invokeHandleMethod
然后有两种运行方式
取决于synchronizeOnSession true同步 false 不同步
分析checkAndPrepare 在父类WebContentGenerator中定义
然后分析invokeHandleMethod
/**
* Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView}
* if view resolution is required.
* @since 4.2
* @see #createInvocableHandlerMethod(HandlerMethod)
*/
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
if (logger.isDebugEnabled()) {
logger.debug("Found concurrent result value [" + result + "]");
}
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
首先使用request和reponse创建webRequest
接着对webDataBinderFactory ModelFactory ServletInvocableHandlerMethod变量定义和初始化
还有3步
1.新建mv容器
2.执行请求
3.完成后置处理
这里太复杂了后续更新感觉自己讲的和屎一样
涉及到很多的组件
大概可以看出
handleInternal3步
准备参数 参数6个来源
执行请求 ServletInvocableHandlerMethod组件执行请求
处理返回值 扫尾工作Model中参数缓存和 ModelAndView的创建。