为了账号安全,请及时绑定邮箱和手机立即绑定

HandlerAdapter

标签:
Java

HandlerAdapter

what

  1. HandlerAdapter从字面意思就是处理适配器,也就是handler的适配器模式
  2. DispatcherServlet 通过适配器来执行具体的Handler,开发者也是通过适配器来扩展Handler
  3. 源码如下
public interface HandlerAdapter {

    /**
     * Given a handler instance, return whether or not this {@code HandlerAdapter}
     * can support it. Typical HandlerAdapters will base the decision on the handler
     * type. HandlerAdapters will usually only support one handler type each.
     * <p>A typical implementation:
     * <p>{@code
     * return (handler instanceof MyHandler);
     * }
     * @param handler handler object to check
     * @return whether or not this object can use the given handler
     */
    boolean supports(Object handler);

    /**
     * Use the given handler to handle this request.
     * The workflow that is required may vary widely.
     * @param request current HTTP request
     * @param response current HTTP response
     * @param handler handler to use. This object must have previously been passed
     * to the {@code supports} method of this interface, which must have
     * returned {@code true}.
     * @throws Exception in case of errors
     * @return ModelAndView object with the name of the view and the required
     * model data, or {@code null} if the request has been handled directly
     */
    @Nullable
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    /**
     * Same contract as for HttpServlet's {@code getLastModified} method.
     * Can simply return -1 if there's no support in the handler class.
     * @param request current HTTP request
     * @param handler handler to use
     * @return the lastModified value for the given handler
     * @see javax.servlet.http.HttpServlet#getLastModified
     * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
     */
    long getLastModified(HttpServletRequest request, Object handler);

}

why

  1. 针对不同类型handler,需要不同的HandlerAdapter来适配,然后DispatchServlet会根据已经加载的HandlerAdapter集合,选择最适合当前Hander【Handler是根据当前请求path从HandlerMapping中获取的】的HandlerAdapter,然后调用ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)方法,获取ModelAndView对象
  2. 比如之前文章中 springMVC路由中 讲到的SimplController这种类型的Handler,就用SimpleControllerHandlerAdapter这种适配器来针对这种Handler来做适配,如下
    可以看出是先根据supports方法来判断是否支持某种类型的Handler,SimpleControllerHanderAdapter就仅仅支持实现了Controller接口的Handler
    然后调用Hander方法,其实就是调用Controller的handleRequest方法直接处理请求,返回ModelAndView对象

    
    public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Controller);
    }
    
    @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;
    }

}


**how**
1. DispatchServlet 首先是初始化HandlerAdapt,在Servlet的init方法中加载,其实就是从spring上下文中收集出所有的HandlerAdapter类型的bean,然后排下序就可以了

private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null;

    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<>(matchingBeans.values());
            // We keep HandlerAdapters in sorted order.
            AnnotationAwareOrderComparator.sort(this.handlerAdapters);
        }
    }
    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.
        }
    }
}
2. 初始化完成之后,当一个请求进来之后,首先会根据HandlerMapping获取对应的HandlerExecutionChain,然后根据其中的Handler类型找到适合的HandlerAdapt,最后开始执行Handler,然后返回ModelAndView对象

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter ha : this.handlerAdapters) {
if (logger.isTraceEnabled()) {
logger.trace("Testing handler adapter [" + ha + "]");
}
if (ha.supports(handler)) {
return ha;
}
}
}
}



<br/>
>微信公众号:宋坤明
 更多精彩请参考 完整版系列 [请参考此博文](https://mp.weixin.qq.com/s?__biz=MzU3MDQyODI1OA==&mid=2247483766&idx=1&sn=4746b214390cb6ce9b8bde7291f09ed3&chksm=fceedf7bcb99566d93c416407e24e695e2ff6ae783620a22dee2e8d46516f6db4223d7d6e68b&scene=21#wechat_redirect) 也可以直接关注我
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消