• HandlerAdapter接口类的简介说明


    转自:

    HandlerAdapter接口类的简介说明

    下文笔者将对HandlerAdapter接口类进行简介说明,如下所示:

    HandlerAdapter接口实现类的作用:
        对用户请求过来的方法进行相应的处理,
    	在SpringMVC中通过使用HandlerAdapter中的处理函数进行相关的方法运行
    

    HandlerAdapter类继承

    HandlerAdapter(接口)
        AbstractHandlerMethodAapter
    	   RequestMappingHandlerAdapter
    	AnnotationMethodHandlerAdapter
    	HttpRequestHandlerAdapter
    	SimpleControllerHandlerAdapter
    	SimpleServletHandlerAdapter
    

    HandlerAdapter接口定义

    public interface HandlerAdapter {  
        //检测是否支持传入的Handler
        boolean supports(Object handler);  
        //使用Handler处理请求
        ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;  
        //获取Last-Modified值
        long getLastModified(HttpServletRequest request, Object handler);  
    }
    

    DispatcherServlet中注册HandlerAdapter流程

    DispatcherServlet中使用initHandlerAdapters方法
    当没有对HandlerAdapter对象进行默认设置时,此时DispatcherServlet将加载三个默认的HandlerAdapter对象
    HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和 AnnotationMethodHandlerAdapter
    例:

    private void initHandlerAdapters(ApplicationContext context) {
        this.handlerAdapters = null;
        if (this.detectAllHandlerAdapters) {
            // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
            Map matchingBeans =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerAdapters = new ArrayList(matchingBeans.values());
                // We keep HandlerAdapters in sorted order.
                OrderComparator.sort(this.handlerAdapters);
            }
        }
        else {
            try {
                HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
                this.handlerAdapters = Collections.singletonList(ha);
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default HandlerAdapter later.
            }
        }
    
        // Ensure we have at least some HandlerAdapters, by registering
        // default HandlerAdapters if no other adapters are found.
        if (this.handlerAdapters == null) {
            this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
            if (logger.isDebugEnabled()) {
                logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
            }
        }
    }
    

    HandlerMapping匹配Handler对象的方式

    使用handlerMapping传过来的Handler对象同DispatcherServlet集合属性handlerAdapter中的 HandlerAdapter一一匹配
    当存在支持Handler对象的HandlerAdapter
    则HandlerAdapter就会调用自己的 handle方法处理请求

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        int interceptorIndex = -1;
    
        try {
            ModelAndView mv;
            boolean errorView = false;
            try {
                processedRequest = checkMultipart(request);
                // Determine handler for the current request.
                mappedHandler = getHandler(processedRequest, false);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }
                //获取合适的HandlerAdapter实现类  
                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()) {
                        String requestUri = urlPathHelper.getRequestUri(request);
                        logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                // Apply preHandle methods of registered interceptors.
                HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
                if (interceptors != null) {
                    for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); return; } interceptorIndex = i; } } // 执行真正的请求操作 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation? if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // Apply postHandle methods of registered interceptors. if (interceptors != null) { for (int i = interceptors.length - 1; i >= 0; i--) {
                        HandlerInterceptor interceptor = interceptors[i];
                        interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
                    }
                }
            }
            catch (ModelAndViewDefiningException ex) {
                logger.debug("ModelAndViewDefiningException encountered", ex);
                mv = ex.getModelAndView();
            }
            catch (Exception ex) {
                Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
                mv = processHandlerException(processedRequest, response, handler, ex);
                errorView = (mv != null);
            }
    
            // Did the handler return a view to render?
            if (mv != null && !mv.wasCleared()) {
                render(mv, processedRequest, response);
                if (errorView) {
                    WebUtils.clearErrorRequestAttributes(request);
                }
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
                            "': assuming HandlerAdapter completed request handling");
                }
            }
    
            // Trigger after-completion for successful outcome.
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
        }
    
        catch (Exception ex) {
            // Trigger after-completion for thrown exception.
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
            throw ex;
        }
        catch (Error err) {
            ServletException ex = new NestedServletException("Handler processing failed", err);
            // Trigger after-completion for thrown exception.
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
            throw ex;
        }
    
        finally {
            // Clean up any resources used by a multipart request.
            if (processedRequest != request) {
                cleanupMultipart(processedRequest);
            }
        }
    }
  • 相关阅读:
    Linux编辑器-gcc/g++使用
    千万级订单生成的痛点与架构
    FreeRTOS源码阅读笔记1--task.c
    题目 1055: 二级C语言-进制转换
    SDL2 简明教程(二):创建一个空的窗口
    【wp】2023第七届HECTF信息安全挑战赛 Web
    分布式系列精讲 分布式系统和单体系统之间到底有什么区别?
    生产设备上的静电该如何处理?
    pnpm为什么卸载卸载不干净
    51单片机-(中断系统)
  • 原文地址:https://blog.csdn.net/qq_25073223/article/details/127799741