Administrator
发布于 2022-10-25 / 48 阅读
0
0

SpringMVC运行流程

SpringMVC运行流程:

4和5版本都差不多,只是中间的过程有点差别,前面的源码分析有点乱,以这篇为准

1、所有请求,前端控制器(DispatcherServlet)收到请求,调用doDispatch进行处理
2、根据HandlerMapping中保存的请求映射信息找到,处理当前请求的,处理器执行链(包含拦截器)
3、根据当前处理器找到他的HandlerAdapter(适配器)
4、拦截器的preHandle先执行
5、适配器执行目标方法,并返回ModelAndView
          1)、ModelAttribute注解标注的方法提前运行
          2)、执行目标方法的时候(确定目标方法用的参数)
                    1)、有注解
                    	1)、请求参数注解
                        2)、ModelAttribute;sessionAttribute注解,
                        	1)、只有ModelAttribute注解,有就拿,拿不到就新建
                            2)、sessionAttribute注解中也有,那么拿得到就拿,拿不到就抛异常
                    2)、没注解:
                             1)、 看是否Model、Map以及其他的
                              2)、如果是自定义类型
                                             1)、从隐含模型中看有没有,如果有就从隐含模型中拿
                                              2)、如果没有,再看是否SessionAttributes标注的属性,
                                              如果是从Session中拿,如果拿不到会抛异常
                                             3)、都不是,就利用反射创建对象
6、拦截器的postHandle执行
7、处理结果;(页面渲染流程)
             1)、如果有异常使用异常解析器处理异常;处理完后还会返回ModelAndView
              2)、调用render进行页面渲染
                         1)、视图解析器根据视图名得到视图对象
                         2)、视图对象调用render方法;
               3)、执行拦截器的afterCompletion;

Image [55]
 

SpringMVC与Spring整合

web.xml

<display-name>Archetype Created Web Application</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <!--SpringMVC思想是有一个前端控制器能拦截所有请求,并智能派发
      前端控制器是一个Servlet;应该在web.xml配置
  -->

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--
           servlet启动加载,servlet原本是第一次访问创建对象;
           load-on-startup:服务器启动时创建对象;值越小优先级越高
       -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <!--
        /*和/都是拦截所有请求;/:会拦截所有请求,但是不会拦截*.jsp;保证jsp访问正常;
                           /*:的范围更大;会拦截*.jsp;一旦拦截jsp页面就不能正常显示
    -->

        <url-pattern>/</url-pattern>
    </servlet-mapping>

在web.xml中,一般会指定两个容器,一个是Spring的,一个是SpringMVC的。分别是上述代码的第一第二个。
Spring在启动的时候,会加载两个容器。

 
image-1666681411031

目的

SpringMVC和Spring整合的目的;分工明确;
SpringMVC的配置文件就来配置和网站转发逻辑以及网站功能有关的
(视图解析器,文件上传解析器,支持ajax,xxx);

Spring的配置文件来配置和业务有关的(事务控制,数据源,xxx);

带来的问题

Spring是一个父容器,SpringMVC是一个子容器;
子容器还可以引用父容器的组件;
父容器不能引用子容器的组件;

即:假设你的controller是在SpringMVC配置文件中扫描的,你的service是在Spring配置文件扫描,那么
你就不能在service中注入Controller。

Image [56]


评论