springMVC (三) HandlerAdapter

来源:互联网 发布:tumblr类似的软件 编辑:程序博客网 时间:2024/06/05 20:41

DispatcherServlet中根据handler找到HandlerAdapter方法

/** * 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");}

接口HandlerAdapter,supports方法

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 */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);}

处理实现Controller接口的SimpleControllerHandlerAdapter,过程比较简单,就是直接调用handleRequest方法

public class SimpleControllerHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {return (handler instanceof Controller);}@Overridepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return ((Controller) handler).handleRequest(request, response);}@Overridepublic long getLastModified(HttpServletRequest request, Object handler) {if (handler instanceof LastModified) {return ((LastModified) handler).getLastModified(request);}return -1L;}}
处理requestMapping注解的RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter

AbstractHandlerMethodAdapter中

public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {/**     * {@inheritDoc} <p>This implementation expects the handler to be an {@link HandlerMethod}.     *     * @param handler the handler instance to check     * @return whether or not this adapter can adapt the given handler     */    @Override    public final boolean supports(Object handler) {        return handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler);    }    /**     * Given a handler method, return whether or not this adapter can support it.     *     * @param handlerMethod the handler method to check     * @return whether or not this adapter can adapt the given method     */    protected abstract boolean supportsInternal(HandlerMethod handlerMethod);//在RequestMappingHandlerAdapter中总是返回true       /**     * {@inheritDoc} <p>This implementation expects the handler to be an {@link HandlerMethod}.     */    @Override    public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        return handleInternal(request, response, (HandlerMethod) handler);    }    /**     * Use the given handler method to handle the request.     *     * @param request current HTTP request     * @param response current HTTP response     * @param handlerMethod handler method to use. This object must have previously been passed to the     * {@link #supportsInternal(HandlerMethod)} this interface, which must have returned {@code true}.     * @return ModelAndView object with the name of the view and the required model data, or {@code null} if     * the request has been handled directly     * @throws Exception in case of errors     */    protected abstract ModelAndView handleInternal(HttpServletRequest request,                                                   HttpServletResponse response,                                                   HandlerMethod handlerMethod) throws Exception;}

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapterimplements BeanFactoryAware, InitializingBean {       @Override    protected final ModelAndView handleInternal(HttpServletRequest request,            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {        if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {            // Always prevent caching in case of session attribute management.            checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);        }        else {            // Uses configured default cacheSeconds setting.            checkAndPrepare(request, response, true);        }        // Execute invokeHandlerMethod in synchronized block if required.        if (this.synchronizeOnSession) {            HttpSession session = request.getSession(false);            if (session != null) {                Object mutex = WebUtils.getSessionMutex(session);                synchronized (mutex) {                    return invokeHandleMethod(request, response, handlerMethod);                }            }        }        return invokeHandleMethod(request, response, handlerMethod);    }}


调用过程挺复杂的,没看太懂,看懂再记录


0 0