SpringMVC源码分析-HandlerAdapter(1)-初始化和简单实现

一,HandlerAdapters的初始化

DispatcherServlet-onRefresh初始化HandlerAdapters

/**
 * This implementation calls {@link #initStrategies}.
 */
@Override
protected void onRefresh(ApplicationContext context) {
    initStrategies(context);
}

/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    // 初始化HandlerAdapters
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
    initFlashMapManager(context);
}

initHandlerAdapters-初始化HandlerAdapters

/**
* Initialize the HandlerAdapters used by this class.
* <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
* we default to SimpleControllerHandlerAdapter.
*/
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;

// 加载所有实现了HandlerAdapter接口的bean
if (this.detectAllHandlerAdapters) {
    // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
    Map<String, HandlerAdapter> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
    if (!matchingBeans.isEmpty()) {
        this.handlerAdapters = new ArrayList<HandlerAdapter>(matchingBeans.values());
        // We keep HandlerAdapters in sorted order.
        AnnotationAwareOrderComparator.sort(this.handlerAdapters);
    }
}
// 只加载bean name="handlerAdapter"的handlerAdapter
else {
    try {
        HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
        this.handlerAdapters = Collections.singletonList(ha);
    }
    catch (NoSuchBeanDefinitionException ex) {
        // Ignore, we'll add a default HandlerAdapter later.
    }
}

// 如果仍未找到,从DispatcherServlet.properties加载默认配置
// Ensure we have at least some HandlerAdapters, by registering
// default HandlerAdapters if no other adapters are found.
if (this.handlerAdapters == null) {
    this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
    if (logger.isDebugEnabled()) {
        logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
    }
}
}

detectAllHandlerAdapters属性-是否发现所有HandlerAdapters

1)默认为true,加载当前系统中所有实现了HandlerAdapter接口的bean到handlerAdapters
2)此属性可通过web.xml中DispatcherServlet的初始参数进行修改
<init-param>
    <param-name>detectAllHandlerAdapters</param-name>
    <param-value>false</param-value>
</init-param>
detectAllHandlerAdapters值为false时,只加载bean name="handlerAdapter"的handlerAdapter

3)加载不到的情况下将按照DispatcherServlet.properties中所定义的
org.springframework.web.servlet.HandlerAdapter中的内容来加载缺省的handlerAdapter。

DispatcherServlet.properties配置文件-org.springframework.web.servlet.HandlerAdapter

org.springframework.web.servlet.HandlerAdapter=
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

二,请求处理流程

DispatcherServlet#doService调用了doDispatch方法


/**
 * Process the actual dispatching to the handler.
 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
 * to find the first that supports the handler class.
 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
 * themselves to decide which methods are acceptable.
 * @param request current HTTP request
 * @param response current HTTP response
 * @throws Exception in case of any kind of processing failure
 */
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;

    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
        ModelAndView mv = null;
        Exception dispatchException = null;

        try {
            processedRequest = checkMultipart(request);
            multipartRequestParsed = (processedRequest != request);

            // Determine handler for the current request.
            mappedHandler = getHandler(processedRequest);
            if (mappedHandler == null || mappedHandler.getHandler() == null) {
                noHandlerFound(processedRequest, response);
                return;
            }

            // 获取与处理器相匹配的handlerAdapter
            // Determine handler adapter for the current request.
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

            // 如果是GET请求,如果内容没有变化的话,则直接返回
            // Process last-modified header, if supported by the handler.
            String method = request.getMethod();
            boolean isGet = "GET".equals(method);
            if (isGet || "HEAD".equals(method)) {
                long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                if (logger.isDebugEnabled()) {
                    logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                }
                if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                    return;
                }
            }

            // 调用执行器链中的拦截器,就是循环装配好的执行器链,执行
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }

            // 执行handle
            // Actually invoke the handler.
            mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

            if (asyncManager.isConcurrentHandlingStarted()) {
                return;
            }

            // 如果返回的ModelAndView不为null,并且没有设置view,设置默认的view。
            applyDefaultViewName(processedRequest, mv);
            // 处理拦截器的postHandle。
            mappedHandler.applyPostHandle(processedRequest, response, mv);
        }
        catch (Exception ex) {
            dispatchException = ex;
        }
        catch (Throwable err) {
            // As of 4.3, we're processing Errors thrown from handler methods as well,
            // making them available for @ExceptionHandler methods and other scenarios.
            dispatchException = new NestedServletException("Handler dispatch failed", err);
        }
        // 如果出现异常,返回异常页面。
        // 如果没有异常,ModelAndView不为null,则正常渲染页面,调用拦截器的afterCompletion方法
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    catch (Exception ex) {
        triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    }
    catch (Throwable err) {
        triggerAfterCompletion(processedRequest, response, mappedHandler,
                new NestedServletException("Handler processing failed", err));
    }
    finally {
        if (asyncManager.isConcurrentHandlingStarted()) {
            // Instead of postHandle and afterCompletion
            if (mappedHandler != null) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            }
        }
        else {
            // Clean up any resources used by a multipart request.
            if (multipartRequestParsed) {
                cleanupMultipart(processedRequest);
            }
        }
    }
}

doDispatch整个流程中,涉及HandlerAdapter的有以下两处:

1,获取与处理器相匹配的handlerAdapter

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

getHandlerAdapter的入参mappedHandler:

HandlerExecutionChain mappedHandler = getHandler(processedRequest);
根据request拿到HandlerExecutionChain对象
包含一个处理器handler(如HandlerMethod对象),多个HandlerInterceptor拦截器对象

getHandlerAdapter源码:

/**
 * Return the HandlerAdapter for this handler object.
 * @param handler the handler object to find an adapter for
 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
 */
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    for (HandlerAdapter ha : this.handlerAdapters) {
        if (logger.isTraceEnabled()) {
            logger.trace("Testing handler adapter [" + ha + "]");
        }
        if (ha.supports(handler)) {
            return ha;
        }
    }
    throw new ServletException("No adapter for handler [" + handler +
            "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

遍历前面加载的handlerAdapters(全部handlerAdapter)找出能够处理handler的handlerAdapter

注:handlerAdapters中包含多种实现了handlerAdapters接口的handlerAdapter
supports用于判断是否支持处理handler,不同的handlerAdapter实现对不同handler的具体处理

2,执行handle

ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

handle也是handlerAdapter接口的一个方法,用于HandlerAdapter的具体处理

到这里前置的一些内容完成了,我们可以开始分析HandlerAdapter了


三,HandlerAdapter

HandlerAdapter的作用:

之前一步,HandlerMapping,通过request找到对应的处理器Handler
接下来在handlerAdapters找到可以处理该handler类型的handlerAdapter
HandlerAdapter使用Handler对用户请求进行具体处理,最终返回ModelAndView

HandlerAdapter即适配器模式,用于统一不同handler的接口调用

HandlerAdapter接口:

package org.springframework.web.servlet;

public interface HandlerAdapter {

    // 是否支持传入的Handler
    boolean supports(Object handler);

    // 使用Handler处理请求
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    // 获取资源的LastModified值
    long getLastModified(HttpServletRequest request, Object handler);

}

四,HandlerAdapter继承体系

HandlerAdapter继承体系:

HandlerAdapter结构

从图中可以看出HandlerAdapter共有5类Adapter

HttpRequestHandlerAdapter,
SimpleServletHandlerAdapter
SimpleControllerHandlerAdapter,
分别适配HttpRequest,Servlet,Controller类型的Handler
处理固定类型的Handler,内部调用固定方法进行处理

AnnotationMethodHandlerAdapter标记了@Deprecated已被弃用
用于适配注解类处理器,如经常使用的@Controller的这类处理器

HttpRequestHandlerAdapter的实现就非常复杂了
所处理的Handler可以是任意方法,参数的类型和数量也不确定

五,HttpRequestHandlerAdapter

适配处理器类型:

@Override
public boolean supports(Object handler) {
    return (handler instanceof HttpRequestHandler);
}
处理实现了HttpRequestHandler接口的处理器,
这类处理器的作用是处理通过SpringMVC来访问的静态资源的请求

处理逻辑:

@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, 
        HttpServletResponse response, Object handler)throws Exception {

    ((HttpRequestHandler) handler).handleRequest(request, response);

    return null;
}
直接调用HttpRequestHandler#handleRequest,返回值为null
通过改写HttpServletResponse实现前后端交互

六,SimpleServletHandlerAdapter

适配处理器类型:

@Override
public boolean supports(Object handler) {
    return (handler instanceof Servlet);
}
适配实现了Servlet接口或Servlet的子类的处理器,
可以在web.xml里面配置Servlet,也可以用SpringMVC来配置Servlet
此HandlerAdapter较少使用,默认加载的handlerAdapters中没有这个

处理逻辑:

@Override
public ModelAndView handle(HttpServletRequest request, 
            HttpServletResponse response, Object handler)throws Exception {

    ((Servlet) handler).service(request, response);
    return null;
}
调用Servlet#service对handler进行处理

七,SimpleControllerHandlerAdapter

适配处理器类型:

@Override
public boolean supports(Object handler) {
    return (handler instanceof Controller);
}
适配实现了Controller接口或Controller接口子类的处理器,
如:自己写的Controller继承自MultiActionController,由SimpleControllerHandlerAdapter适配

处理逻辑:

@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {

    return ((Controller) handler).handleRequest(request, response);
}
直接调用Controller#handleRequest(具体实现类的handleRequest方法)
适配SimpleUrlHandlerMapping和BeanNameUrlHandlerMapping的映射

这一节主要介绍了关于HandlerAdapter的整体流程

从DispatchServlet#onRefresh初始化九大组件,找到HandlerAdapter的初始化加载策略,即注册
DispatcherServlet#doService调用doDispatch方法,
看到HandlerAdapter在整个请求处理的过程中的作用和角色
HandlerAdapter接口定义和HandlerAdapter继承体系
介绍了除RequestMappingHandlerAdapter外的另外三种adapter的实现

下一节介绍HandlerAdapter的核心RequestMappingHandlerAdapter

猜你喜欢

转载自blog.csdn.net/abap_brave/article/details/80942509