Bootstrap

springmvc的核心组件和执行流程

1.springmvc的核心组件

以下是 Spring MVC 的核心组件:
1.DispatcherServlet(前端控制器):

定义:DispatcherServlet 是 Spring MVC 的前端控制器(Front
Controller),它作为应用程序的入口点,负责处理所有的请求和响应。 作用:DispatcherServlet 根据请求的 URL
和配置的处理器映射,将请求分派给适当的处理器(Controller)进行处理,并获取处理结果。

2.HandlerMapping(处理器映射):

HandlerMapping 将请求映射到相应的处理器(Controller)进行处理。 Spring MVC 提供了多种
HandlerMapping 的实现,包括注解驱动的 RequestMappingHandlerMapping、基于接口的
BeanNameUrlHandlerMapping 等。 Controller(控制器:

3.Controller 是处理请求并返回响应的组件。

在 Spring MVC 中,可以使用多种方式定义 Controller,包括使用注解标记的控制器类、实现特定接口的控制器类等。

4.HandlerAdapter(处理器适配器):

HandlerAdapter 负责将请求分派给相应的 Controller 进行处理。 HandlerAdapter 根据不同的
Controller 类型调用相应的方法,并处理请求的参数绑定、数据转换、验证等操作。

5.ViewResolver(视图解析器):

ViewResolver 将逻辑视图名称解析为实际的视图对象。 Spring MVC 提供了多种 ViewResolver 的实现,包括
InternalResourceViewResolver(用于解析 JSP 视图)、ThymeleafViewResolver(用于解析
Thymeleaf 模板视图)等

6.View(视图):

View 负责渲染模型数据并生成最终的响应内容。 不同的视图技术有不同的实现,如 JSP 视图、Thymeleaf
视图、FreeMarker 视图等

2.springmvc的执行流程

  1. 用户向服务器发送请求,请求被springmvc前端控制器dispatcherservlet捕获
  • dispatcherservlet对请求去url进行解析,得到请求次元标识符url,判断url对应的映射:
    不存在:
    1.再判断配置了mvc:default-servlet-handler
    2.如果没有配置,则控制台包映射查找不到,客户端展示404错误
    3.如果有配置:测访问目标资源(一般为静态资源),找不到客户端也会报404的错误
    存在:
    根据url,调用handlereMapping获得该handler配置的所有相关对象(包括handler对象以及handler对象对应的拦截器),最后以handlerExecutionChain执行链对象的形式返回
    2. dispatcherservlet根据获得的handler选择一个合适的handleradapter
    • 如果成功获得handleradapter,此时将开始执行拦截器的prehandler方法(正向)
    • 提取request中的模型数据,填充handler入参,开始执行handler方法,处理请求,再填充handler的入参过程中,根据你的配置,spring将帮你做一些额外的工作
      (1).httpmessagerconveter:将请求消息转换为一个对象,将对象转换为指定的相应消息
      (2).数据转换:将请求消息进行数据转换,如string转换为integer等
      (3).数据格式化:将请求消息进行数据格式化,将字符串转化为格式化数字或者格式化日期
      (4).数据验证:检验数据的有效性(长度,格式),将验证结果储存到bindingresult或者error中
      - handler执行完成后,向dispatcherservlet返回一个modelandview对象
      • 此时将开始执行拦截器的posthandle方法逆向
      • 根据返回的modelandview(此时会判断是否存在异常,如果存在异常则执行handlerresolver进行异常处理)选择一个适合的viewresolver进行视图解析,根据model和view,来渲染视图
      • 渲染视图完毕执行拦截器的aftercompletion方法
      • 将渲染结果返回给客户端

代码展示:

用户向服务器发送请求,
调用DispatcherServlet中继承下来的service方法,对请求方式进行判断

 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
        if (httpMethod != HttpMethod.PATCH && httpMethod != null) {
            super.service(request, response);
        } else {
            this.processRequest(request, response);
        }

    }

然后调用this.processRequest(request, response);在这个方法中紧接着调用了this.doService(request, response);再调 this.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 mv = null;
                Exception dispatchException = null;
                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    /*根据handlerMapping获取到执行连对象,执行链对象中有三个属性
                        private final Object handler;执行器对象
                        private List<HandlerInterceptor> interceptorList;配置的拦截器
                        private int interceptorIndex;用于记录拦截器的执行个数,起始为-1*/
                        
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
     
      // 根据this.getHandlerAdapter(mappedHandler.getHandler())获取到合适的执行器适配器对象
      
                     HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }
                    //执行连接器的的PreHandle方法,执行顺序按照配置的先后顺序,其中默认的是第一个执行的

                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
                    //执行handler方法实现controller中的方法,并返回一个modelAndView对象

                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);
                    //执行拦截器中的PostHandle方法,执行顺序按照配置的反序进行
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
            //执行拦截器中的AfterCompletion(方法,执行顺序按照配置的反序进行
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }
;