在两个WAR之间共享应用程序上下文?

| 有没有办法在两次部署的战争之间共享应用程序上下文?一战需要连接另一战的服务,我不知道从哪里开始。     
已邀请:
诸如tomcat之类的Web应用程序容器的一般用途是,每个应用程序都能够独立运行(因此您可以停止和启动单个应用程序而不会影响其他应用程序),这意味着在开发它们的过程中,可能需要付出很多精力,专门针对阻止您这样做。因此,即使您发现了漏洞,也建议不要使用它,除非设计人员建议或至少批准了该漏洞。 我建议您开始寻找其他解决方案。例如: 您是否真的需要共享对象实例?如果它们是无状态的,则可能不需要,您只需在每个应用程序中运行上下文的副本即可。 您是否可以将要共享的代码分成公开了REST服务的第三个WAR?或者可能是现有的WAR之一可以充当服务。     
我们的团队有相同的要求-在Tomcat中的多个WAR之间共享Spring Bean,说实话,诸如“不要这样做”之类的回答没有帮助。 需求源于以下事实:我们在Tomcat上运行了一个多WAR应用程序,并且所有WAR都需要访问同一RDBMS才能保留信息。我们正在使用Spring和Hibernate访问RDBM,并且所有WAR共享相同的架构,并且理想情况下可以使用相同的Hibernate SessionFactory和Spring事务管理器。 有关如何执行的答案发布在这里: StackOverflow:在EAR中共享ApplicationContext 总结一下,您可以在web.xml中执行以下操作:
<context-param>
  <param-name>parentContextKey</param-name>
  <param-value>sharedContext</param-value>
</context-param>
<context-param>
  <param-name>locatorFactorySelector</param-name>
  <param-value>classpath:beanRefContext.xml</param-value>
</context-param>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:yourWarSpecificAppContext.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
其中beanRefContext.xml包含:
<beans>
  <bean id=\"sharedContext\" class=\"org.springframework.context.support.ClassPathXmlApplicationContext\">
    <constructor-arg>
      <list>
        <value>classpath:yourSharedAppContext.xml</value>
      </list>
    </constructor-arg>
  </bean>
</beans>
这使用Spring ContextSingletonBeanFactoryLocator公开并共享父上下文(在本例中,使用名称\“ sharedContext \”)。当第一个WAR引用共享上下文时,它将被延迟加载。 您在共享上下文中引用的任何bean都必须对所有WAR都可访问,这意味着它们不能从特定WAR中的WEB-INF / class或WEB-INF / lib加载。必须使用EAR文件或通过将包含bean(和依赖项)的jar放在Tomcat共享的“ lib \”文件夹($ CATALINA_HOME / lib)中来共享它们,这是我们团队所做的。 合理的警告是,如果使用这种方法,则大多数JAR可能位于共享的lib文件夹中,而不是单个webapp中。对于我们的项目,这是有道理的,因为大多数Web应用程序共享和访问相同的后端服务。 由于顽固的Tomcat开发人员可能会反对将大量代码放入Tomcat共享的lib目录中,因此我仅列举一些其他建议的答案可能不起作用的原因。 对每个WAR使用单独的应用程序上下文将意味着具有多个数据库连接池,每个WAR使用一个连接池,并对每个WAR单独进行昂贵的Hibernate SessionFactory初始化,这会增加服务器启动时间和内存消耗。更一般而言,它不允许在同一Tomcat中运行的Web应用程序之间共享共享后端服务的状态。 至少在我们的情况下,将持久性代码放入单独的WAR中并使用REST调用对开发人员来说是完全不方便的,并且与直接调用共享Bean相比,这增加了到达数据库的路径长度。     
我认为您应该检查一下内容丰富的博客文章:在多战Spring应用程序中使用共享的父应用程序上下文     
如果您启动嵌入式码头服务器并从启动和配置码头服务器的类中访问两个Web应用程序,则可能是一种方法。 看到: 嵌入码头     
您是否需要共享运行时上下文,还是只想在两个应用程序之间重用bean定义? 如果只是后者,那么您可以轻松地将常见的Spring上下文XML文件提取到某个共享的依赖项中,然后在两个Web应用程序之间重用JAR。但是,如果您需要每个应用程序中的bean /服务相互通信,则需要一个不同的选项。     
如果上下文不存在,则可以将其绑定到JNDI。 这样做的代价是,每个Web应用程序的上下文都必须以某种方式意识到它可能不是主要的。 另外,您需要特别注意比赛条件,例如 第一个webapp启动,检测到没有上下文 第一个Web应用程序开始构建上下文 第二个webapp启动,检测到没有上下文 第二个Webapp开始构建上下文 第一个webapp完成构建上下文并将其绑定 第二个webapp完成构建上下文并将其绑定 恭喜,您已经从第一个Webapp的上下文中丢失了所有bean     
同意@RichardSmith,接受的答案对我没有帮助。理查德的答案有助于指出正确的方向,但我使用的是Jetty,所以不能使用EAR。我最终使用服务器上下文在两次大战之间共享一个对象-即使在热(重新)部署的Web应用程序中也可以使用: https://stackoverflow.com/a/46968645/1287091 也可能是一种适用于Tomcat的方法。     

要回复问题请先登录注册