多个Spring根WebApplicationContexts

时间:2010-12-02 04:36:24

标签: java spring tomcat

我有一个tomcat服务器,它有两个具有相同部署战争的webapps(foo和bar)。部署使用标准的Spring / Hibernate设置。我假设这两个webapps会启动并完全独立运行,但事实并非如此 - webapp foo正常加载,但webapp bar有一些奇怪的行为 - 就好像它使用的是webapp中的一些相同的bean FOO。例如,当bar启动时(第二个webapp启动),c3p0抱怨它已经注册 - 大概是在webapp foo中。再一次,我试图使两个webapps完全独立,这样两个c3p0 / hibernateSessionFactory bean就无法相互了解。

在进行一些研究时,我一直认为在两个webapps中都使用了相同的Spring root WebApplicationContext。如果是这种情况,我怎样才能使每个webapp(在同一个tomcat服务器上)完全独立?还有什么可能导致这个问题吗?

web.xml的相关摘录:

<web-app>
    <context-param>
        <param-name>org.hibernate.tags.sessionFactory</param-name>
        <param-value>hibernate/SessionFactory</param-value>
    </context-param>

    <context-param>
        <param-name>contextConfigLocation</param-name> 
        <param-value>/WEB-INF/context/*Context.xml</param-value>
    </context-param>

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

    <servlet>
        <servlet-name>fooServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
</web-app>

1 个答案:

答案 0 :(得分:1)

我怀疑了。是不是加载问题的根源?

我想你问题的直接原因是一些Spring类被加载一次并在这两个WAR之间共享。我不知道该类的确切名称,但Spring需要在某些静态字段中存储一些共享信息(至少是对应用程序上下文的引用)。然后,当两个WAR看到该类的相同副本时,则两个应用程序都会看到此静态字段的相同状态。我想在你的设置中Spring只创建一个应用程序上下文(当第二个应该创建时,Spring会找到一个现有的应用程序上下文并使用它)。

我发现这个问题可能有两个原因:

  • 这是一个类加载问题。我不是那个进入tomcat并且不知道如何配置它,但是通常在JavaEE应用服务器中有一些方法可以为WAR配置类加载。
  • 或者这是一种内存泄漏。也许这个类(及其静态字段)是从以前的部署中重用的(不太可能,你的描述往往暗示你在一个新的tomcat实例上遇到问题)。您可以通过确保在(重新)启动tomcat之后出现问题来排除这种可能性。

更新: 如果这是关于类加载,我会尝试找出哪个类(及其静态字段)导致问题。这可能不是您的类,而是您在应用程序中使用的某些第三方库类。阅读http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html后,您可以看到Tomcat为每个应用程序使用不同的不相关类加载器。但是,如果他们不知道该类,则他们共享他们委托的父类加载器。 同样,我不知道你的确切设置和一些Tomcat的特性,但是......在Tomcat中是不是可以将一些库(JAR),比如c3p0或Spring,放在一些常见的'lib'文件夹中(文档说$ CATALINA_HOME / lib中)?在这种情况下,使用父类加载器(tomcat文档中称为“Common”的加载器)加载来自这些JAR的类。这意味着它们只加载一次。

为了简化故事,我想原因是你的$ CATALINA_HOME / lib中的一个JAR有一些严重依赖于某些静态字段的类。使用Common类加载器加载JAR的Tomcat策略导致所有应用程序共享这些静态字段的状态。

我告诉过你这只是一种怀疑和猜测吗?