关于HandlerAdapter

这个接口有3个方法supports handler getLastModified
HandlerAdapter是具体通过使用Handler的来干活的。
每个HandlerAdapter封装了一种Hanlder的具体使用方法。
HandlerAdapter的子类有

AbstractMethodHandler RequestMappingHandlerAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
SimpleServletHandlerAdapter

后3个格式形式固定,只调用固定的方法就可以了

RequestMappingHandlerAdapter处理的Handler可以是任意方法。

而调用采用是反射的方法 但是参数解析麻烦

首先HttpHandlerAdapter

public class HttpRequestHandlerAdapter implements HandlerAdapter {

    //判断此Handler是不是HttpRequestHandler
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof HttpRequestHandler);
    }

   //调用HttpRequestHandler的handlerRequest
    @Override
    @Nullable
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        ((HttpRequestHandler) handler).handleRequest(request, response);
        return null;
    }
     //同样的调用httphandler的方法
    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        if (handler instanceof LastModified) {
            return ((LastModified) handler).getLastModified(request);
        }
        return -1L;
    }
}

SimpleServletHandlerAdapter

public class SimpleServletHandlerAdapter implements HandlerAdapter {
//判断是否是servlet
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Servlet);
    }
//调用service方法
    @Override
    @Nullable
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        ((Servlet) handler).service(request, response);
        return null;
    }

    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        return -1;
    }
}

SimpleControllerHandlerAdapter

public class SimpleControllerHandlerAdapter implements HandlerAdapter {
//判断是否是Controller
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Controller);
    }
//调用handlerRequest方法
    @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;
    }

}

发现supports是判断是否符合指定类型
handler不同的adapter调用不同的方法
http和controller调用handleRequest,而servlet调用service

我们知道AbstractHandlerMethodAdapter的3个方法调用子类的模板方法
还是上源码吧

public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {

    private int order = Ordered.LOWEST_PRECEDENCE;


    public AbstractHandlerMethodAdapter() {
        // no restriction of HTTP methods by default
        super(false);
    }


    /**
     * Specify the order value for this HandlerAdapter bean.
     * <p>Default value is {@code Integer.MAX_VALUE}, meaning that it's non-ordered.
     * @see org.springframework.core.Ordered#getOrder()
     */
    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }


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

    /**
     * This implementation expects the handler to be an {@link HandlerMethod}.
     */
    @Override
    @Nullable
    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
     */
    @Nullable
    protected abstract ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;

    /**
     * This implementation expects the handler to be an {@link HandlerMethod}.
     */
    @Override
    public final long getLastModified(HttpServletRequest request, Object handler) {
        return getLastModifiedInternal(request, (HandlerMethod) handler);
    }

    /**
     * Same contract as for {@link javax.servlet.http.HttpServlet#getLastModified(HttpServletRequest)}.
     * @param request current HTTP request
     * @param handlerMethod handler method to use
     * @return the lastModified value for the given handler
     */
    protected abstract long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod);

但是在supports方法中必须保证handler是HandlerMethod类型 ,另外实现了Order接口,可以在配置时设置顺序。

然后分析所有组件中最复杂的RequestMappingHandlerAdapter

它的supportsInternal直接返回true 不增加判断条件

/**
     * Always return {@code true} since any method argument and return value
     * type will be processed in some way. A method argument not recognized
     * by any HandlerMethodArgumentResolver is interpreted as a request parameter
     * if it is a simple type, or as a model attribute otherwise. A return value
     * not recognized by any HandlerMethodReturnValueHandler will be interpreted
     * as a model attribute.
     */
    @Override
    protected boolean supportsInternal(HandlerMethod handlerMethod) {
        return true;
    }

没啥可说的

/**
     * This implementation always returns -1. An {@code @RequestMapping} method can
     * calculate the lastModified value, call {@link WebRequest#checkNotModified(long)},
     * and return {@code null} if the result of that call is {@code true}.
     */
    @Override
    protected long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod) {
        return -1;
    }

模板方法直接返回-1,这些都简单
最主要是handleInternal


大致分为3步
1. 备好处理数据
2. 使用处理器处理请求
3. 处理返回值,将不同类型值统一生成ModelAndView类型。

@Override
    protected ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ModelAndView mav;
        checkRequest(request);

        // 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) {
                    mav = invokeHandlerMethod(request, response, handlerMethod);
                }
            }
            else {
                // No HttpSession available -> no mutex necessary
                mav = invokeHandlerMethod(request, response, handlerMethod);
            }
        }
        else {
            // No synchronization on session demanded at all...
            mav = invokeHandlerMethod(request, response, handlerMethod);
        }

        if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
            if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
                applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
            }
            else {
                prepareResponse(response);
            }
        }

        return mav;
    }

先分析第一步
首先要理解准备参数的话
需要思考那些参数需要绑定:
根据方法确定 处理器 注解了ModelAttribute InitBinder的方法
参数值得来源:
6个来源
request相关参数 url post参数 请求头
cookie参数
session参数
设置到FlashMap中的参数 用于redirect参数传递
sessionAttributes传递的参数
modelAttributes设置的参数
具体绑定的方法

参数的解析是通过HandlerMethodArgumentResolver完成

WebDataBinder @InitBinder来初始化 使用同一套ArguementResolver来解析。

由于它的组件过多 首先有必要进行自身分析结构

首先看一看它有哪些组件
(一)adapter的创建过程

它的创建是在afterPropertiesSet方法中实现

内容初始化argumentResolvers,
6个属性


    @Override
    public void afterPropertiesSet() {
        // Do this first, it may add ResponseBody advice beans
        initControllerAdviceCache();

        if (this.argumentResolvers == null) {
            List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
            this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
        }
        if (this.initBinderArgumentResolvers == null) {
            List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
            this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
        }
        if (this.returnValueHandlers == null) {
            List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
            this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
        }
    }

argumentResolvers
initBinderArguementResolvers
returnValueHandlers
modelAttributeAdviceCache initBinderAdviceCache
responseBodyAdvice

adapter的使用过程
handleInternal主要两句代码 checkAndPrepare invokeHandleMethod
然后有两种运行方式
取决于synchronizeOnSession true同步 false 不同步
分析checkAndPrepare 在父类WebContentGenerator中定义

然后分析invokeHandleMethod


    /**
     * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView}
     * if view resolution is required.
     * @since 4.2
     * @see #createInvocableHandlerMethod(HandlerMethod)
     */
    @Nullable
    protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        try {
            WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
            ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

            ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
            if (this.argumentResolvers != null) {
                invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
            }
            if (this.returnValueHandlers != null) {
                invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
            }
            invocableMethod.setDataBinderFactory(binderFactory);
            invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

            ModelAndViewContainer mavContainer = new ModelAndViewContainer();
            mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
            modelFactory.initModel(webRequest, mavContainer, invocableMethod);
            mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

            AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
            asyncWebRequest.setTimeout(this.asyncRequestTimeout);

            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
            asyncManager.setTaskExecutor(this.taskExecutor);
            asyncManager.setAsyncWebRequest(asyncWebRequest);
            asyncManager.registerCallableInterceptors(this.callableInterceptors);
            asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

            if (asyncManager.hasConcurrentResult()) {
                Object result = asyncManager.getConcurrentResult();
                mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
                asyncManager.clearConcurrentResult();
                if (logger.isDebugEnabled()) {
                    logger.debug("Found concurrent result value [" + result + "]");
                }
                invocableMethod = invocableMethod.wrapConcurrentResult(result);
            }

            invocableMethod.invokeAndHandle(webRequest, mavContainer);
            if (asyncManager.isConcurrentHandlingStarted()) {
                return null;
            }

            return getModelAndView(mavContainer, modelFactory, webRequest);
        }
        finally {
            webRequest.requestCompleted();
        }
    }

首先使用request和reponse创建webRequest
接着对webDataBinderFactory ModelFactory ServletInvocableHandlerMethod变量定义和初始化
还有3步
1.新建mv容器
2.执行请求
3.完成后置处理

这里太复杂了后续更新感觉自己讲的和屎一样


涉及到很多的组件

大概可以看出
handleInternal3步
准备参数 参数6个来源
执行请求 ServletInvocableHandlerMethod组件执行请求
处理返回值 扫尾工作Model中参数缓存和 ModelAndView的创建。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值