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
- 针对不同类型handler,需要不同的HandlerAdapter来适配,然后DispatchServlet会根据已经加载的HandlerAdapter集合,选择最适合当前Hander【Handler是根据当前请求path从HandlerMapping中获取的】的HandlerAdapter,然后调用ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)方法,获取ModelAndView对象
-
比如之前文章中 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) 也可以直接关注我