一、什么是HandlerAdapter
Note that a handler can be of type Object. This is to enable handlers from other frameworks to be integrated with this framework without custom coding.
boolean supports(Object handler)
Given a handler instance, return whether or not this HandlerAdapter can support it.
HandlerAdapter 接口实现类:
1. HttpRequestHandlerAdapter : 要求handler实现HttpRequestHandler接口
public class HttpRequestHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
2. SimpleControllerHandlerAdapter:要求handler实现Controller接口,该接口的方法参数为ModelAndView
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; } }
3. AbstracthandlerMethodAdapter的handle()使用模板方法,调用子类handleInternal()实现
@Override public final boolean supports(Object handler) { return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler)); } protected abstract boolean supportsInternal(HandlerMethod handlerMethod); @Override public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); } protected abstract ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;
AbstracthandlerMethodAdapter及其子类RequestMappingHandlerAdapter的supportsInternal()方法
/** * 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; }
二、什么是HandlerMethod:封装了请求处理方法的参数和返回值,及该方法上的注解
Encapsulates information about a handler method consisting of a method and a bean. Provides convenient access to method parameters, the method return value, method annotations, etc.
The class may be created with a bean instance or with a bean name (e.g. lazy-init bean, prototype bean).
Use createWithResolvedBean()
to obtain a HandlerMethod
instance with a bean instance resolved through the associated BeanFactory
.
三、什么时候使用HandlerAdapter
1. DispatchServlet protected void doDispatch()方法会获取相应的HandlerAdapter
// Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
在以前的文章中,已经说过RequestMappingHandlerAdapter是处理输入输出的关键点,也是spring根据相应的路径查找对应的处理器的关键点
RequestMappingHandlerAdapter的handleInternal()会调用invokeHandlerMethod()
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 ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); 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(); } }
3.一个请求过来时,InvocableHandlerMethod的执行变量
从上面的分析看到,处理请求时,会调用invokeAndHandle(),最终是doInvoke执行
4. 疑问:这些HandlerMethond是什么时候载入系统的
解答:系统启动的时候执行registerHandlerMethod()方法,创建HandlerMethod实例
三、HandlerMapping VS HandlerAdapter
The strategy interface HandlerAdapter takes the role of invoking handler methods selected by some HandlerMapping.