• SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter处理器适配器底层


      ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------

     

     先放一张图

    很熟悉啊,之前就看过,我们之前已经把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模型和视图对象,一路返回,到中央调度器

     
  • 相关阅读:
    java基础知识复习
    红黑二叉查找树(原理、实现)
    Django admin
    redis+sentinel 安装与配置
    浅谈saltstack
    python3 通过smtplib模块发送邮件
    django 自定义分页模块
    chouti项目
    Django 进阶篇二
    Django 进阶篇
  • 原文地址:https://www.cnblogs.com/DawnCHENXI/p/8641579.html
Copyright © 2020-2023  润新知