Web环境中Spring MVC(一)

来源:互联网 发布:linux route -p 编辑:程序博客网 时间:2024/06/01 16:01


      之前学习Spring MVC时对它很是不了解,只停留在能用的层次上,但是对于它的工作机制和配置模棱另可,在淘淘中经历了整合SSM的过程,其中突然对Spring以及Spring MC突然有了些感触,于是通过对 《Spring技术内幕》、博客http://www.cnblogs.com/Hxinguan/p/6407882.html 的学习,加深了印象。更多内容如下:


      在web环境中, spring MVC是建立在IOC容器的基础上,要了解spring mvc,首先要了解Spring IOC容器是如何在web环境中被载入并起作用的。

  spring IOC是一个独立的模块,并不是直接关联web容器的,在web环境中使用IOC容器,就需要把IOC容器导入,在web环境中建立起来。下面以tomcat作为web容器的例子。在tomcat中,web.xml是应用部署文件,web文件如下。

View Code
 1 <!DOCTYPE web-app PUBLIC 2  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 3  "http://java.sun.com/dtd/web-app_2_3.dtd" > 4  5 <web-app>   6   <display-name>springmvcTest</display-name> 7   <!-- spring 配置 --> 8   <context-param> 9       <param-name>contextConfigLocation</param-name>10       <param-value>/WEB-INF/applicationContext.xml</param-value>11   </context-param>12   13   <filter>14       <filter-name>characterEncoding</filter-name>15       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>16      <init-param>17          <param-name>encoding</param-name>18          <param-value>utf-8</param-value>19      </init-param>20   </filter>21   <filter-mapping>22       <filter-name>characterEncoding</filter-name>23       <url-pattern>/*</url-pattern>24   </filter-mapping>25   <listener>26       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>27   </listener>28   29   <!-- 配置springmvc -->30   <servlet>31       <servlet-name>springmvcTest</servlet-name>32       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>33       <init-param>34           <param-name>contextConfigLocation</param-name>35           <param-value>classpath:springmvc.xml</param-value>36       </init-param>37       <load-on-startup>1</load-on-startup>38   </servlet>39   <servlet-mapping>40       <servlet-name>springmvcTest</servlet-name>41       <url-pattern>*.do</url-pattern>42   </servlet-mapping>43   44    <servlet-mapping>45       <servlet-name>springmvcTest</servlet-name>46       <url-pattern>*.html</url-pattern>47   </servlet-mapping>48   49   <!-- <welcome-file-list>50         <welcome-file>index.do</welcome-file>51     </welcome-file-list> -->52 </web-app>


  在web文件中,有两个非常重要的类,一个是ContextLoaderListener,一个是DispatcherServlet。DispatcherServlet定义了对应的URL映射,这些URL映射为servlet指定了需要处理的HTTP请求。ContextLoaderListener被定义为一个监听器,这个监听器负责完成IOC容器在web环境中的启动工作。web.xml文件中,还引入了两个文件,一个是/WEB-INF/applicationContext.xml文件,另一个是classpath:springmvc.xml文件,其中applicationContext.xml文件就是sping IOC容器配置的xml文件。

 

   DispatcherServlet和ContextLoaderListener提供了在web容器中对spring的接口,也就是说,这些接口与web容器耦合是通过ServletContext来实现的。这个ServletContext为springIOC容器提供了一个宿主环境,在宿主环境中,spring mvc建立一个ioc容器的体系,这个IOC容器体系是通过ContextLoaderListener的初始化来建立的,在IOC容器建立后,把DispatcherServlet作为spring mvc处理web请求转发建立起来,从而完成响应的HTTP请求的准备。


2.  ContextLoaderListener的初始化和spring IOC的建立


    IOC容器启动的过程就是建立上下文的过程,该上下文是与ServletContext相伴而生的,同时也是IOC容器在web应用环境的具体表现之一。由ContextLoaderListener启动的上下文为根上下文。在根上下文的基础上,还有一个与web MVC相关的上下文来保存的控制器(DispatcherServlet)需要的MVC对象,作为根上下文的子上下文,构成一个层次化的上下文体系。在web容器启动的过程,首先建立根上下文,然后建立这个上下文体系的,这个上下文体系的建立是由ContextLoader来完成。

  也就是说/WEB-INF/applicationContext.xml配置的spring IOC容器是由ContextLoaderListener这个类进行初始化的,这样就完成了根上下文在web容器中的创建。这个根上下文是作为web容器中唯一的实例而存在,如果在初始化过程中,发现已经有根上下文被创建了,就会抛出异常。根上下文被创建了,就会被保存到web容器的ServletContext中,以共需要时使用。

3. DispatcherServlet的初始化和MVC IoC容器的建立

  完成了对ContextLoaderListener的初始化以后,也就是创建完根上下文后,Web容器开始初始化DispatcherServlet,DispatcherServlet会建立自己的上下文来持有spring mvc的bean对象,在建立自己持有的IoC容器时,会从ServletContext中得到根上下文作为DispatcherServlet持有上下文的双亲对象。有了这个根上下文,再对自己持有的上下文进行初始化,最后把自己持有的这个上下文保存到ServletContext中,供以后检索使用。

  作为servlet,DispatcherServlet的启动与servlet的启动过程是相联系的,在Servlet的初始化过程中,Servlet的init方法会被调用,以进行初始化。接下来就是执行DispatcherServlet持有的IoC容器的初始化过程,在初始化这个过程中,一个新的上下文被建立起来,DispatcherServlet持有的上下文被设置为根上下文的子上下文。可以认为,根上下文是和web应用相对应的上下文,而DispatcherServlet持有的上下文是和servlet对应的上下文。而在web容器中,往往可以容纳多个Servlet存在。对于应用在web容器中的上下文体系,一个根上下文可以作为许多Servlet上下文的双亲上下文。了解了这一点,对在web环境中的Ioc容器中的bean设置和检索会有更多的了解,在向IOC容器getBean时候,IOC容器会首先像其双亲去getBean,也就是说,在根上下文定义的bean是可以被各个servlet持有的上下文得到和共享的。最后,DispatcherServlet给自己持有的上下文命名,并把它设置到web容器的上下文中,这个名称和在web.xml中设置的DispatcherServlet的servlet名称相关,从而保证了这个上下文在web环境上下文体系中的唯一性。



4. 总结


  在web环境中建立IOC容器体系,首先是通过ContextLoaderListener来建立spring 容器,然后在建立DispatcherServlet的IoC容器,假如我们在service层引用controller,即/WEB-INF/applicationContext.xml中的bean引用classpath:springmvc.xml中的bean,是会报错的,会报如下错误:No qualifying bean found for dependency.....即没有找到指定的bean。还有就是为什么controller一般放在classpath:springmvc.xml文件中进行配置,DispatcherServlet直接打交道的是controller,首先会从DispatcherServlet持有的IOC容器中寻找相对应的controller,找不到才会到spring IOC容器里寻找。


       关于Spring 容器和Spring MVC 的关系和更多理解,请参考《Spring 三级父子容器》

 

0 0
原创粉丝点击