HandlerAdapter
what
- HandlerAdapter从字面意思就是处理适配器,也就是handler的适配器模式
- DispatcherServlet 通过适配器来执行具体的Handler,开发者也是通过适配器来扩展Handler
-
源码如下
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路由中](https://mp.weixin.qq.com/s?__biz=MzU3MDQyODI1OA==&mid=2247483765&idx=1&sn=51259a24421649c51e4a67350f3e9b38&chksm=fceedf78cb99566ec8267de7e417e96eab41c4f8ade4dbbc261243b5fade70fee41437983572#rd) 讲到的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) 也可以直接关注我
![图注:宋坤明公众号](https://mmbiz.qpic.cn/mmbiz_jpg/5DXUjepfcKRADpOh6YXAkxQUwXtJRpScrB8Gqd1o24egkKicFjZ5mJG3rX5cTERPwgTSP1PPM5ZiatydHRltw52g/0?wx_fmt=jpeg)
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦