全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 8 分钟 ✍️ juanwangdev

HandlerAdapter

HandlerAdapter采用适配器模式,统一不同Handler类型的调用方式,屏蔽Handler实现差异。

接口定义

Java
public interface HandlerAdapter {
    // 是否支持该Handler类型
    boolean supports(Object handler);

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

    // 获取最后修改时间(已废弃)
    long getLastModified(HttpServletRequest request, Object handler);
}

内置适配器类型

适配器支持Handler说明
RequestMappingHandlerAdapterHandlerMethod处理@RequestMapping方法
HttpRequestHandlerAdapterHttpRequestHandler处理静态资源
SimpleControllerHandlerAdapterController处理传统Controller
SimpleHandlerHandlerAdapterServlet处理Servlet

RequestMappingHandlerAdapter

核心属性

Java
public class RequestMappingHandlerAdapter
        extends AbstractHandlerMethodAdapter
        implements BeanFactoryAware, InitializingBean {

    // 参数解析器
    private HandlerMethodArgumentResolverComposite argumentResolvers;

    // 返回值处理器
    private HandlerMethodReturnValueHandlerComposite returnValueHandlers;

    // 自定义参数解析器
    private List<HandlerMethodArgumentResolver> customArgumentResolvers;

    // 自定义返回值处理器
    private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;

    // 数据绑定工厂
    private WebDataBinderFactory dataBinderFactory;
}

supports实现

Java
@Override
public boolean supports(Object handler) {
    return handler instanceof HandlerMethod;
}

handle核心流程

Java
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
        HttpServletResponse response, HandlerMethod handlerMethod) {

    // 检查请求方法是否支持
    checkRequest(request);

    // 执行Handler方法
    ModelAndView mav;
    if (isSynchronizeOnSession()) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            synchronized (session) {
                mav = invokeHandlerMethod(request, response, handlerMethod);
            }
        } else {
            mav = invokeHandlerMethod(request, response, handlerMethod);
        }
    } else {
        mav = invokeHandlerMethod(request, response, handlerMethod);
    }

    return mav;
}

protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
        HttpServletResponse response, HandlerMethod handlerMethod) {

    ServletWebRequest webRequest = new ServletWebRequest(request, response);

    try {
        WebDataBinderFactory binderFactory = createDataBinderFactory(handlerMethod);

        // 创建ModelAndView容器
        ModelAndViewContainer mavContainer = new ModelAndViewContainer();

        // 创建调用器
        ServletInvocableHandlerMethod invocableMethod =
            createInvocableHandlerMethod(handlerMethod);

        // 设置参数解析器
        invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);

        // 设置返回值处理器
        invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);

        // 设置数据绑定工厂
        invocableMethod.setDataBinderFactory(binderFactory);

        // 执行方法
        invocableMethod.invokeAndHandle(webRequest, mavContainer);

        return getModelAndView(mavContainer, model, webRequest);

    } finally {
        webRequest.requestCompleted();
    }
}

ServletInvocableHandlerMethod

Java
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {

    public void invokeAndHandle(ServletWebRequest webRequest,
            ModelAndViewContainer mavContainer, Object... providedArgs) {

        // 1. 解析参数并调用方法
        Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

        // 2. 设置响应状态
        setResponseStatus(webRequest);

        // 3. 处理返回值
        if (returnValue == null) {
            if (isRequestNotModified(webRequest) || getResponseStatus() != null) {
                mavContainer.setRequestHandled(true);
                return;
            }
        } else if (StringUtils.hasText(getResponseStatusReason())) {
            mavContainer.setRequestHandled(true);
            return;
        }

        // 4. 调用返回值处理器
        mavContainer.setRequestHandled(false);
        this.returnValueHandlers.handleReturnValue(
            returnValue, getReturnValueType(), mavContainer, webRequest);
    }
}

参数解析器链

HandlerMethodArgumentResolverComposite

Java
public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {

    private final List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>();

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return getArgumentResolver(parameter) != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
            ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
            WebDataBinderFactory binderFactory) {

        HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
        if (resolver == null) {
            throw new IllegalArgumentException("Unsupported parameter type");
        }
        return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
    }

    private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
        for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
            if (resolver.supportsParameter(parameter)) {
                return resolver;
            }
        }
        return null;
    }
}

内置参数解析器

Java
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
    List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

    // 基于注解
    resolvers.add(new RequestParamMethodArgumentResolver(false));
    resolvers.add(new PathVariableMethodArgumentResolver());
    resolvers.add(new MatrixVariableMethodArgumentResolver());
    resolvers.add(new RequestHeaderMethodArgumentResolver());
    resolvers.add(new RequestBodyMethodArgumentResolver());
    resolvers.add(new RequestPartMethodArgumentResolver());
    resolvers.add(new ModelAttributeMethodProcessor(false));
    resolvers.add(new SessionAttributeMethodArgumentResolver());

    // 基于类型
    resolvers.add(new ServletRequestMethodArgumentResolver());
    resolvers.add(new ServletResponseMethodArgumentResolver());
    resolvers.add(new HttpSessionMethodArgumentResolver());
    resolvers.add(new ModelMethodProcessor());
    resolvers.add(new ErrorsMethodArgumentResolver());

    // 自定义解析器
    resolvers.addAll(getCustomArgumentResolvers());

    // 兜底解析器
    resolvers.add(new RequestParamMethodArgumentResolver(true));
    resolvers.add(new ModelAttributeMethodProcessor(true));

    return resolvers;
}

返回值处理器链

HandlerMethodReturnValueHandlerComposite

Java
public class HandlerMethodReturnValueHandlerComposite
        implements HandlerMethodReturnValueHandler {

    private final List<HandlerMethodReturnValueHandler> returnValueHandlers = new ArrayList<>();

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return getReturnValueHandler(returnType) != null;
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
            ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {

        HandlerMethodReturnValueHandler handler = getReturnValueHandler(returnType);
        if (handler == null) {
            throw new IllegalArgumentException("Unknown return value type");
        }
        handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
    }
}

内置返回值处理器

Java
private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
    List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();

    // ModelAndView相关
    handlers.add(new ModelAndViewMethodReturnValueHandler());
    handlers.add(new ModelMethodProcessor());
    handlers.add(new ViewMethodReturnValueHandler());
    handlers.add(new ViewNameMethodReturnValueHandler());

    // 响应体相关
    handlers.add(new ResponseBodyMethodReturnValueHandler());
    handlers.add(new RequestResponseBodyMethodProcessor());
    handlers.add(new HttpEntityMethodProcessor());

    // 其他类型
    handlers.add(new HttpHeadersReturnValueHandler());
    handlers.add(new CallableMethodReturnValueHandler());
    handlers.add(new DeferredResultMethodReturnValueHandler());

    // 自定义处理器
    handlers.addAll(getCustomReturnValueHandlers());

    return handlers;
}

HttpRequestHandlerAdapter

Java
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) {
        ((HttpRequestHandler) handler).handleRequest(request, response);
        return null;
    }
}

// 静态资源处理器
@Component
public class StaticResourceHandler implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest request,
            HttpServletResponse response) {
        Resource resource = getResource(request);
        response.setContentType(resource.getContentType());
        response.setContentLengthLong(resource.contentLength());
        StreamUtils.copy(resource.getInputStream(), response.getOutputStream());
    }
}

SimpleControllerHandlerAdapter

Java
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) {
        return ((Controller) handler).handleRequest(request, response);
    }
}

// 传统Controller实现
@Component("/user")
public class UserController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) {
        ModelAndView mav = new ModelAndView("user");
        mav.addObject("users", userService.findAll());
        return mav;
    }
}

DispatcherServlet选择适配器

Java
protected HandlerAdapter getHandlerAdapter(Object handler) {
    if (this.handlerAdapters != null) {
        for (HandlerAdapter adapter : this.handlerAdapters) {
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
    }
    throw new ServletException("No adapter for handler [" + handler + "]");
}

执行流程图

Java
DispatcherServlet.doDispatch()
        ↓
getHandlerAdapter(handler)
        ↓ 遍历适配器链
        ↓ 找到supports=true的适配器
        ↓
RequestMappingHandlerAdapter.handle()
        ↓
invokeHandlerMethod()
        ↓
ServletInvocableHandlerMethod.invokeAndHandle()
        ├─ argumentResolvers.resolveArgument() 参数解析
        ├─ invokeForRequest() 执行方法
        ├─ returnValueHandlers.handleReturnValue() 处理返回值
        ↓
ModelAndView

自定义HandlerAdapter

text
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(Object handler) {
        return handler instanceof CustomHandlerInterface;
    }

    @Override
    public ModelAndView handle(HttpServletRequest request,
            HttpServletResponse response, Object handler) {
        CustomHandlerInterface customHandler = (CustomHandlerInterface) handler;
        Object result = customHandler.process(request, response);

        // 处理返回结果
        if (result instanceof ModelAndView) {
            return (ModelAndView) result;
        } else if (result instanceof String) {
            return new ModelAndView((String) result);
        } else {
            response.setContentType("application/json");
            response.getWriter().write(toJson(result));
            return null;
        }
    }
}

HandlerAdapter通过适配器模式统一Handler调用,责任链模式协调参数解析和返回值处理。

要点总结

  1. HandlerAdapter接口定义Handler调用契约
  2. RequestMappingHandlerAdapter处理HandlerMethod
  3. 参数解析器链负责参数绑定
  4. 返回值处理器链负责响应生成
  5. 自定义适配器支持新的Handler类型

jwdev/articles/SPRINGMVC/专家/容器级WEB组件扩展/容器级WEB组件扩展/HandlerAdapter.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 请求参数绑定与校验
下一篇 → HandlerMapping
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库