dispatch-servlet.xml与applicationContext.xml

dispatcher-servlet.xml(在你的项目中也可能写作springmvc-serlvet.xml、spring-serlvet.xml等等)和applicationContext.xml中的根元素都是,两者也同样都可以托管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设置为1,即servlet在应用启动时初始化,dispatcher-servlet.xml的初始化也会在根上下文之后。在一个应用中,可以有多个像dispatcher-servlet.xml一样的上下文,每一个各自服务于一个spring的servlet,比如spring1-servlet.xml用于名字为spring1的servlet,spring2-servlet.xml用于名字为spring2的servlet,并通过在web.xml中的配置进行绑定,如下:

web.xml:

spring1
org.springframework.web.servlet.DispatcherServlet
          
contextConfigLocation

        /WEB-INF/spring1-servlet.xml



spring1              
/spring1/



spring2
org.springframework.web.servlet.DispatcherServlet          
  
contextConfigLocation

/WEB-INF/spring2-servlet.xml

spring2 

/spring2/


从示例中可以看出,我们分别定义了两个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,如下:



    org.springframework.web.context.ContextLoaderListener
 

 
    contextConfigLocation
    WEB-INF/spring-servlet.xml
 

spring

org.springframework.web.servlet.DispatcherServlet       


spring              
/

这样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中的


    org.springframework.web.context.ContextLoaderListener
 

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

你可能感兴趣的:(spring,springmvc)