SpringMVC(四):什么是HandlerAdapter

时间:2023-12-26 17:08:37

一、什么是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;
}

SpringMVC(四):什么是HandlerAdapter

二、什么是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.

SpringMVC(四):什么是HandlerAdapter

三、什么时候使用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执行

SpringMVC(四):什么是HandlerAdapter

4.  疑问:这些HandlerMethond是什么时候载入系统的

解答:系统启动的时候执行registerHandlerMethod()方法,创建HandlerMethod实例

SpringMVC(四):什么是HandlerAdapter

三、HandlerMapping VS HandlerAdapter

The strategy interface HandlerAdapter takes the role of invoking handler methods selected by some HandlerMapping.