dispatch-servlet.xml与applicationContext.xml

dispatcher-servlet.xml(在你的项目中也可能写作springmvc-serlvet.xml、spring-serlvet.xml等等)和applicationContext.xml中的根元素都是<beans>,两者也同样都可以托管java bean,那么两者的区别何在呢?

1.两者的区别:

spring允许你使用树形的结构定义多个上下文,而applicationContext.xml定义的是“root webapp context”,直译过来就是根应用上下文。而dispatcher-servlet.xml定义一个servlet的应用上下文,是applicationContext.xml上下文的子类。在初始化时,applicationContext.xml首先初始化,而dispatcher-servlet.xml在对应的servlet实例化时启动,因此applicationContext.xml初始化在前,而dispatcher-servlet.xml初始化在后。即使将spring servlet设置为<load-on-startup>1</load-on-startup>,即servlet在应用启动时初始化,dispatcher-servlet.xml的初始化也会在根上下文之后。在一个应用中,可以有多个像dispatcher-servlet.xml一样的上下文,每一个各自服务于一个spring的servlet,比如spring1-servlet.xml用于名字为spring1的servlet,spring2-servlet.xml用于名字为spring2的servlet,并通过在web.xml中的配置进行绑定,如下:

web.xml:

<!-- spring1 servlet -->

<servlet>

<servlet-name>spring1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>   
<param-name>contextConfigLocation</param-name>
<!-- 指定spring1-servlet.xml为spring1这个servlet的配置文件 -->
        <param-value>/WEB-INF/spring1-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring1</servlet-name>              
<url-pattern>/spring1/</url-pattern>
</servlet-mapping>

<!-- spring2 servlet -->
<servlet>
<servlet-name>spring2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>          
<init-param>   
<param-name>contextConfigLocation</param-name>
<!-- 指定spring2-servlet.xml为spring2这个servlet的配置文件 -->
<param-value>/WEB-INF/spring2-servlet.xml</param-value></init-param>
</servlet>

<servlet-mapping>

<servlet-name>spring2</servlet-name> 

<url-pattern>/spring2/</url-pattern>

</servlet-mapping>

从示例中可以看出,我们分别定义了两个spring servlet,第一个叫spring1,其配置文件为spring1-servlet.xml,其上下文也就是
spring1-servlet.xml;第二个叫spring2,其上下文为spring2-servlet.xml。

2.依赖注入:

spring-servlet.xml中的bean可以引用父类applicationContext.xml上下文中的bean,例如在spring-servlet.xml中定义了一个bean,类名叫A,A类中有一个成员变量是B类的对象,而B类又是applicationContext.xml中的Bean,那么通过@resouce @autowired等注解或者在配置文件中声明都可以引用到B类的这个bean,但是反之则不行。比如B类中有一个A类的成员变量,通过@resource等方式来引用spring-servlet.xml中的A类的bean,在运行时会报错,提示要注入的bean不存在。其实很容易理解,前面说过,applicationContext.xml初始化在先,因此applicationContext.xml中的bean实例化在先,无法获得spring-servlet.xml的bean。不仅如此,也可能由于spring的servlet对应的上下文是子类,可能有多个,因此在spring1-servlet.xml和spring2-servlet.xml中可能有相同的bean类(比如类型相同、id、name都相同),如果作为父类的applicationContext.xml需要子类的bean,那么spring框架应该从哪个子类中获得bean呢?有可能 spring的开发者出于这种考虑,设计了父类上下文中的bean不能引用子类上下文中的bean。

3.dispatch-servlet.xml与applicationContext.xml写成一个文件

可以把这两个文件写成一个,比如spring-servlet.xml,然后在web.xml声明根应用上下文为spring-servlet.xml,如下:


<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/spring-servlet.xml</param-value>
  </context-param>

<servlet>

<servlet-name>spring</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>       
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>              
<url-pattern>/</url-pattern>
</servlet-mapping>

这样spring-servlet.xml同时也具有原来的applicationContext.xml的作用。

但是根据上文,我们知道根上下文是在应用启动时初始化,而servlet对应的上下文随servlet初始化,他们是两个上下文,因此即便是写成同一个文件,也只是使用spring-servlet.xml同时充当根上下文对象,省去了一个xml文件,但是spring-servlet.xml仍会初始化两遍:第一遍是作为根上下文随应用启动时初始化,第二遍是作为spirng servlet对应的上下文随名称为spring的servlet初始化。即如果在spring-servlet.xml声明了一个bean,这个bean会在应用启动时,spring-servlet.xml作为根上下文初始化时,创建一个;然后在servlet启动时,spring-servlet.xml又作为servlet的上下文初始化时,再创建一个。当然,简单的springMVC应用一般只有一个spring servlet,因此applicationContext.xml也可以不用,而把所有的bean都注册到spring servlet对应的上下文,即把web.xml中的

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

这段代码去掉,只保留spring-servlet.xml文件。这种情况下,如果有些bean需要在应用启动时初始化,那么设置spring servlet为<load-on-startup>1</load-on-startup>即可

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值