2014-04-10 94 views
0

我跟着一些Spring MVC的教程和我的web.xml看起来是这样的:在根上下文和servlet上下文中加载应用程序上下文有什么好处吗?

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 


     <param-value>/WEB-INF/spring/root-context.xml, /WEB-INF/spring/appServlet/servlet-context.xml</param-value> 


    </context-param> 

    <!-- Creates the Spring Container shared by all Servlets and Filters --> 
    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <!-- Processes application requests --> 
    <servlet> 
     <servlet-name>appServlet</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 


      <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> 

     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>appServlet</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<session-config> 
    <session-timeout>1</session-timeout> 
</session-config> 

</web-app> 

我的问题是,什么是装载的servlet-context.xml中的根上下文和servlet上下文两个好处?我是一个春季框架新手,我不太了解春季框架。

+0

为了更好地理解在根和应用方面的区别就在这里看我的答复在http://stackoverflow.com/questions/19619539/understanding-contexts-in-spring-mvc/19621534# 19621534 – Shailendra

+0

另外,[this](http://stackoverflow.com/questions/11708967/what-is-the-difference-between-applicationcontext-and-webapplicationcontext-in-s)。除了模块分离以外,没有任何实际的好处。 –

+0

@SotiriosDelimanolis:如果我从根上下文中删除它会发生什么?我的应用程序的工作方式会有什么变化吗? – riship89

回答

0

在Spring中,ApplicationContext可以是分层的。如果您在单个EAR中有多个Web应用程序,那么EAR可以拥有自己的上下文,这是各个Web应用程序上下文的父项。同样在每个Web应用程序中,您也可以拥有一个根上下文和各个子上下文。你可以在web.xml中定义这个层次结构。父上下文可以通过上下文参数来指定:locatorFactorySelector和parentContextKey。通过上下文参数contextConfigLocation的根上下文(context-param中的一个)。子上下文可以在每个servlet定义的init param - param-name属性中指定。

在EAR中有一个jar包含所有常用服务和DAO层代码,并在beanRefContext.xml(基本上是另一个应用程序上下文xml)中定义它们。使这个jar在类路径中可用。

在要引用父上下文代码中的每个应用程序的web.xml文件:

<!-- root application context --> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath:rootContextBeans.xml</param-value> 
</context-param> 
<!-- start shared service layer - parent application context --> 
<context-param> 
    <param-name>locatorFactorySelector</param-name> 
    <param-value>classpath:beanRefContext.xml</param-value> 
</context-param> 
<context-param> 
    <param-name>parentContextKey</param-name> 
    <param-value>servicelayer-context</param-value> 
</context-param> 
<!-- end shared service layer - parent application context --> 
<listener> 
    <listener-class> 
     org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener>  
<servlet> 
    <servlet-name>dispatcherServletApp1</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath*:webApp1.xml</param-value> 
    </init-param> 
</servlet> where beanRefContext.xml will be like: 

<beans> 
    <bean id="servicelayer-context" class="org.springframework.context.support.ClassPathXmlApplicationContext"> 
    <constructor-arg> 
     <list> 
     <value>data-layer-context.xml</value> 
     </list> 
    </constructor-arg> 
    </bean> 
</beans> 

如果你的项目没有多的Web应用程序类型,那么您不需要指定父应用程序上下文。您可以将通用服务和DAO层代码,安全性移至可由dispatcherServlet bean访问(可见)的根应用程序上下文(在上述web.xml中为rootContextBeans.xml)(请记住反向可见性是不可能的)。
在您指定的web.xml中,根上下文contextConfigLocation和servlet contextConfigLocation中的servlet-context.xml。因此,您需要检查在其中定义了哪些bean以及它的准确位置,并在其他位置删除引用。

4

没有很好的理由在servlet和根上下文中注入两次完全相同的配置。大多数Spring MVC应用程序都有一个包含所有服务层/ DAO层bean的根上下文,以及应用程序的每个Spring调度程序servlet的一个servlet上下文,它包含(至少)每个servlet的控制器。

这个想法是,一个应用程序可能有几个servlet调度程序,例如一个用于URL/desktop/*,另一个用于URL/mobile/*,每个都有自己的一组不同的控制器。

一个servlet调度器的控制器是相互隔离的,这意味着尽管它们也是Spring bean,但它们不能相互注入。

根上下文中的服务层和DAO bean在所有的servlet上下文中都是可见的,所以服务层bean可以注入到任何控制器中,而不是相反。

根上下文被认为是控制器servlet上下文/上下文的父项。

这一切都意味着将一组bean彼此隔离,以确保不存在无限的依赖关系。

另外还有一些需要根上下文的Spring框架组件,例如OpenSessionInViewFilter

TLDR:不是,这是不可能在两种情况下注入的servlet-context.xml中,但这不是它怎样来使用:将有两个独立的环境中各类型的两个豆,你也可以拥有交易应用,而另一个没有应用等等,它可以很快产生难以排除故障的错误

相关问题