web环境中的spring MVC

1. web.xml文件的简单详解  

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

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

 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>
View Code

  在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容器里寻找。

原文地址:https://www.cnblogs.com/Hxinguan/p/6407882.html