zoukankan      html  css  js  c++  java
  • SpirngMVC源码分析

    分析过程

      通过 前端控制器源码 分析 SpringMVC 的执行过程

      前端控制器在 web.xml 文件中的配置

    <!-- springmvc 前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等) 
            如果不配置contextConfigLocation,默认加载的是 WEB-INF/servlet名称-servlet.xml (即springmvc-servlet.xml)
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 
            第一种:*.action,访问以.action结尾的由DispatcherServlet进行解析
            第二种: /,所有访问地址都由DispatcherServlet进行解析
                但是对于静态文件的解析,我们需要配置不让DispatcherServlet进行解析
                使用此种方式可以实现Restful风格的URL
            第三种: /* 这种配置不对,使用这种配置,最终要转发到一个jsp页面时,仍然会由DispatcherServlet
                解析jsp,不能根据jsp页面找到Handler,会报错。
         -->
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

      第一步:前端控制器接收请求

        调用doDispatch

        

      

      第二步:前端控制器 调用 处理器映射器 查找 Handler

      (1)

      

      (2)映射器根据 request 中的 URL  找到了 Handler,最后返回了执行器链(链中有 Handler)

      

       

      第三步:调用 处理器适配器 执行 Handler,得到执行的结果ModelAndView

      

       

      第四步:视图渲染,将 Model 的数据填充到 request 域

      (1)获取 ModelAndView 之后,调用 processDispatchResult()方法

      

      

      (2)processDispatchResult()方法中的 render 方法进行视图渲染

      

       

      (3)render方法进行视图解析,得到 view。view继续调用其 redner()方法。

    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // Determine locale for request and apply it to the response.
        Locale locale = this.localeResolver.resolveLocale(request);
        response.setLocale(locale);
    
        View view;
        if (mv.isReference()) {
            // We need to resolve the view name.
            view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
            if (view == null) {
                throw new ServletException("Could not resolve view with name '" + mv.getViewName()
                        + "' in servlet with name '" + getServletName() + "'");
            }
        } else {
            // No need to lookup: the ModelAndView object contains the actual View object.
            view = mv.getView();
            if (view == null) {
                throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a "
                        + "View object in servlet with name '" + getServletName() + "'");
            }
        }
    
        // Delegate to the View object for rendering.
        if (logger.isDebugEnabled()) {
            logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
        }
        try {
            view.render(mv.getModelInternal(), request, response);
        } catch (Exception ex) {
            if (logger.isDebugEnabled()) {
                logger.debug(
                        "Error rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'",
                        ex);
            }
            throw ex;
        }
    }

      (4)然后我们发现 render()方法是 View 接口中的一个方法。

      

      

      (5)我们继续向下找,找到实现 View 接口的抽象类 AbstractView。

       抽象类 AbstractView 中,有 render 方法,render 方法中有 renderMergedOutputModel()方法———渲染合并后的输出模型方法

      

      

      

      (6)在 AbstractView 抽象类的子类的 renderMergedOutputModel()方法(以InternalResourceView类为例)中,调用了父类的 exposeModelAsRequestAttributes()这个方法。

       

      (7)在 exposeModelAsRequestAttributes()这个方法中,循环遍历 Model ,一个一个填充到 Request 域中(即将模型数据填充 到Request域中)

       

      

  • 相关阅读:
    SpringMVC
    SpringMVC
    SpringMVC
    SpringMVC
    JavaWeb
    SpringMVC
    SpringMVC
    Spring
    Spring
    Spring
  • 原文地址:https://www.cnblogs.com/xb1223/p/10186945.html
Copyright © 2011-2022 走看看