springMVC原理总结

 

一.大体流程:

①启动web容器(tomcat,也叫servlet容器)

WebApplicationContext的servlet和Web容器监听器

配置:在web.xml中配置如下:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:smart-context.xml
        </param-value>
    </context-param>

    <!--负责启动spring容器的监听器  还可以声明自启动的Servlet   ContextLoaderServlet-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>    

默认加载配置文件为:/WEB-INF/applicationContext.xml

最终结果:创建spring的IoC容器(默认WebApplicationContext)(根root上下文)与web容器结合。

PS:关于是否有ContextLoaderListener的解释:推荐阅读 博客1 博客2

该IoC容器主要功能:

1、如上配置是Spring集成Web环境的通用配置;一般用于加载除Web层的Bean(如DAO、Service等),以便于与其他任何Web框架集成。

contextConfigLocation:表示用于加载Bean的配置文件;

contextClass:表示用于加载Bean的ApplicationContext实现类,默认WebApplicationC

2、ContextLoaderListener初始化的上下文加载的Bean是对于整个应用程序共享的,不管是使用什么表现层技术,一般如DAO层、Service层Bean;

③配置前端控制器

<servlet>  
        <servlet-name>default</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>classpath:default_servlet.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>default</servlet-name>  
        <url-pattern>/</url-pattern>  
    </servlet-mapping>   

默认配置文件地址:WEB-INF文件路径下查找一个文件,名为[servlet-name]-servlet.xml

最终结果:产生Spring MVC 持有的IoC容器(WebApplicationContext--默认使用XMLWebApplicationContext ),如果有根上下文,就会将springMVC 的上下文当做root上下文的子(继承了父)。

该IoC上下文的作用:

1、供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。

2、DispatcherServlet初始化的上下文加载的Bean是只对Spring Web MVC有效的Bean,如Controller、HandlerMapping、HandlerAdapter等等,该初始化上下文应该只加载Web相关组件。

二.详细流程

Part1:Web容器的启动

           web容器(比如tomcat、jboss、weblogic等)启动的时候,它会为每个web应用程序创建一个ServletContext对象 它代表当前web应用的上下文(注意:是每个web应用有且仅创建一个ServletContext,一个web应用,就是你一个web工程)。一个web中的所有servlet共享一个ServletContext对象,所以可以通过ServletContext对象来实现Servlet之间的通讯。在一个继承自HttpServlet对象的类中,可以通过this.getServletContext来获取。

Part2:SpringIoC容器的启动

① 条件:SpringIoc是一个独立的模块,并不是直接在web容器中发挥作用的,如果在web中使用IoC容器,需要spring为IoC设计一个启动过程,把IoC容器的导入,也就是说IoC容器的导入,是伴随着Web容器启动过程一起进行的。

如何连接web容器(以tomcat为例)和Spring呢?

1、<listener>:

                  ContextLoaderListener:监听器负责完成IoC容器在web环境中的启动工作,提供了在web容器中对spring的接口,这些接口与web容器耦合是通过ServletContext(为Ioc容器提供了一个宿主容器)来实现的。

2、<context-param>:

用来指定SpringIoC容器读取Bean定义的XML文件路径。配置文件中可以看到Spring应用的Bean配置

 ③启动过程:

            1. 启动方式包括3种,这里要讲的事Web容器中IoC的启动方式。(其他两种参考博客

2. ContextLoaderListener/ContextLoader/ServletContextListener

ContextLoaderListener核心是实现了 ServletContextListener 的contextInitialized(建立WebApplicationContext,进而获得ServletContext的引用的过程)和contextDestroyed方法,该方法分别调用了 ContextLoader里面的initWebApplicationContext和closeWebApplicationContext方法。

所以是ContextLoader 实现了这个监听器!

3、具体过程:

先判WebApplicationContext是否已存在,不存在的话则初始化一个XmlWebApplicationContext(WebApplicationContext的子类),并把该实例put到 currentContextPerThread 中。而初始化 XmlWebApplicationContext 时,就跟我们使用 new ClassPathXmlApplicationContext(contextConfigLocation)一样。

                         将我们配置的各种bean都添加到XmlWebApplicationContext中,所以我们知道 ApplicationContext 提供各种 getBean的方法。

                         并且可以发现 ContextLoader还提供了获取当前 WebApplicationContext的静态方法:之所以能获取,是因为initWebApplicationContext初始化方法把创建的XmlWebApplicationContext 塞到了 currentContextPerThread 中。

而最终产生的WebApplicationContext是专门为web应用准备的,他允许从相对于web根目录的路劲中装载配置文件完成初始化工作,从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置在ServletContext中,以便web应用可以访问spring上下文,spring中提供WebApplicationContextUtils的getWebApplicationContext(ServletContext src)方法来获得WebApplicationContext对象。

Part3:SpringMVC的IoC容器的启动

条件:

②如何连接?

1、DispatcherServle

提供了在web容器中对springMVC的接口,作为SpringMVC处理Web请求的转发器建立起来,从而完成了相应HTTP请求的准备。

③初始化过程

首先:HttpServletBean继承HttpServlet:

其中HttpServlet中的方法:

                               init()-->将Servlet初始化参数(init-param)设置到该组件上,通过BeanWrapper简化设值过程,方便后续使用;

initServletBean()-->提供给子类初始化扩展点,该方法由FrameworkServlet覆盖。

之后:FrameworkServlet继承HttpServletBean:

initServletBean()进行Web上下文初始化:① 初始化web上下文 ②提供给子类初始化扩展点;结果:基本上如果ContextLoaderListener加载了上下文将作为根上下文(DispatcherServlet的父容器)。

最后调用了onRefresh()方法执行容器的一些初始化,这个方法由子类实现,来进行扩展。

最后:DispatcherServlet继承FrameworkServlet

实现了onRefresh()方法提供一些前端控制器相关的配置:DispatcherServlet启动时会进行我们需要的Web层Bean的配置,如HandlerMapping、HandlerAdapter等,而且如果我们没有配置,还会给我们提供默认的配置。

          ④结果

从ServletContext中得到根上下文作为DispatcherServlet持有上下文的双亲上下文。

在根上下文基础上,在对自己持有的上下文进行初始化,会建立自己的上下文来持有SPring MVC的bean对象,作为自己持有的IoC容器。

最后把自己持有的这个上下文保存到ServletContext中

Part4:SpringMVC请求分发

①HandlerMapping:

              DispatcherServlet启动时会进行我们需要的Web层Bean的配置,如HandlerMapping、HandlerAdapter等,而且如果我们没有配置,还会给我们提供默认的配置。里面存放了一个list放置url与Controller的映射关系.

②使用HandlerMapping完成对请求的映射处理。

  ③对请求的分发

doService()中完成对http请求的响应。

doDispatcher()完成分发。其中getHandler响应请求,执行Handler得到ModelAndView,交给视图对象呈现。

参考博客:

http://jinnianshilongnian.iteye.com/blog/1602617

https://www.cnblogs.com/09120912zhang/p/7746252.html

https://www.cnblogs.com/xdouby/p/6476750.html

https://blog.youkuaiyun.com/limm33/article/details/51025047

https://blog.youkuaiyun.com/gzu_imis/article/details/18989679

 

推荐一个公众号,免费领架构师学习资料,每周更新优质文章,能学到很多。

评论 55
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值