您的位置:首页 > 编程语言 > Java开发

springMVC (三) HandlerAdapter

2016-05-23 17:07 441 查看
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 {

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

@Override
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;
}

}处理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 AbstractHandlerMethodAdapter
implements 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);
    }
}


调用过程挺复杂的,没看太懂,看懂再记录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: