1. 程式人生 > >SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter處理器適配器底層

SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter處理器適配器底層

下一個 var color abs utils header multipart urn 深度

先放一張圖

技術分享圖片

很熟悉啊,之前就看過,我們之前已經把handlerMapping剖了個底朝天,順著上次的進度,繼續跟,把HandlerAdapter處理器適配器剖一下

它同樣是由中央調度器DispatcherServlet調度到的,所以,還是這個類中找doDispatch(request,response)這個方法,我把有用的代碼,扒下來

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest 
= request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { try { ModelAndView err = null; Exception dispatchException
= null; try { processedRequest = this.checkMultipart(request); multipartRequestParsed = processedRequest != request; mappedHandler = this.getHandler(processedRequest); if(mappedHandler == null || mappedHandler.getHandler() == null
) { this.noHandlerFound(processedRequest, response); return; } //上面的是我說的HandleMapping的執行 流程 //所以從後面的第一行開始看 HandlerAdapter ex = this.getHandlerAdapter(mappedHandler.getHandler());

HandlerExecutionChain mappedHandler這個變量,是處理器執行鏈,它的getHandler方法,就是獲取它裏面的處理器
它外面的this.getHandlerAdpter
點過去追蹤
    protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
//叠代器
        Iterator var2 = this.handlerAdapters.iterator();
//一會要返回去的適配器對象
        HandlerAdapter ha;
        do {
//如果沒有下一個的話。就拋異常
            if(!var2.hasNext()) {
                throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
            }
//將此強轉成為處理器適配器
            ha = (HandlerAdapter)var2.next();
            if(this.logger.isTraceEnabled()) {
                this.logger.trace("Testing handler adapter [" + ha + "]");
            }
        } while(!ha.supports(handler));
//這兒有個適配器模式
        return ha;
    }

這是下載源碼後的最直觀的源碼

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

看ha.sipports(handler)這個方法

找到HandlerAdapter接口

public interface HandlerAdapter {

    boolean supports(Object handler);

    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    long getLastModified(HttpServletRequest request, Object handler);

}

再來看一下自己寫的控制器實現了Controller。這樣就看DispatcherServlet屬性中的HandlerApater誰支持Controller類型的處理器了。在運行的過程中發現SimpleControllerHandlerAdapter是支持Controller類型的控制器的。
來看一下SimpleControllerHandlerAdapter的代碼

找它的實現類:Ctrl+H SimpleControllerHandlerAdapter

public class SimpleControllerHandlerAdapter implements HandlerAdapter {  
  
    public boolean supports(Object handler) {  
        return (handler instanceof Controller);  
    }  
  
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)  
            throws Exception {  
  
        return ((Controller) handler).handleRequest(request, response);  
    }  
  
    public long getLastModified(HttpServletRequest request, Object handler) {  
        if (handler instanceof LastModified) {  
            return ((LastModified) handler).getLastModified(request);  
        }  
        return -1L;  
    }  
  
}  

它support來判斷是否是處理器

拿到處理器在中央調度器一處調用了handle方法

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // Determine handler for the current request.
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // Determine handler adapter for the current request.
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

//就是上面這處

看看handle方法,因為被執行調用到,它返回ModelAndView

裏面return走的handleRequest是Controller接口的,找它的實現類

AbstractController抽象類,它有實現handleRequest

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        // Delegate to WebContentGenerator for checking and preparing.
        checkRequest(request);
        prepareResponse(response);

        // Execute handleRequestInternal in synchronized block if required.
        if (this.synchronizeOnSession) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                Object mutex = WebUtils.getSessionMutex(session);
                synchronized (mutex) {
                    return handleRequestInternal(request, response);
                }
            }
        }

        return handleRequestInternal(request, response);
    }

看到最後面的那個返回值了嗎?是ModelAndView對象,它調用了handleRequestInternal(request,respone)這個方法

還記得AbstractController的實現類嗎?不是有種處理器的定義方法就是繼承AbstractController

package cn.dawn.day04abstractController;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Dawn on 2018/3/19.
 */
//處理器
public class FirstController extends AbstractController {

    protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView me=new ModelAndView();
        me.setViewName("index");
        return me;
    }
}

它的實現類默認要求必須實現handleRequestInternal(request,response)這個方法

所以,理清了吧,再一步步return回去,最後回到了中央調度器

結論,中央處理器DispatcherServlet通過處理器執行鏈找到handlerAdapter處理器適配器,後者調度了它的處理器,通過處理器處理,返回一個ModelAndView模型和視圖對象,一路返回,到中央調度器

 

SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter處理器適配器底層