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

Ste*_*all 11 java spring tomcat dependency-injection war

有没有办法在两次部署的战争之间共享应用程序上下文?一场战争需要接通另一场战争的服务,我不知道从哪里开始.

小智 13

我们的团队也有同样的要求 - 在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>
Run Code Online (Sandbox Code Playgroud)

其中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>
Run Code Online (Sandbox Code Playgroud)

这使用Spring ContextSingletonBeanFactoryLocator来公开和共享父上下文(在本例中使用名称"sharedContext").当第一个WAR引用它时,将延迟加载共享上下文.

无论您在共享上下文中引用的bean都必须可以访问所有WAR,这意味着它们无法从特定WAR中的WEB-INF/classes或WEB-INF/lib加载.必须使用EAR文件共享它们,或者将包含bean(和依赖项)的jar放在Tomcat共享的"lib"文件夹($ CATALINA_HOME/lib)中,这是我们团队所做的.

公平警告,如果您使用此方法,您可能会将大多数JAR放在共享lib文件夹中而不是单独的Web应用程序中.对于我们的项目,这是有道理的,因为大多数webapp共享和访问相同的后端服务.

由于硬核Tomcat开发人员可能会反对将大量代码放入Tomcat共享库目录中,因此我将列举其他建议答案可能不起作用的一些原因.

  • 为每个WAR使用单独的应用程序上下文意味着具有到数据库的多个连接池,每个WAR一个连接池,以及为每个WAR单独初始化昂贵的Hibernate SessionFactory,这会增加服务器启动时间和内存消耗.更一般地说,它不允许在同一Tomcat中运行的Web应用程序之间共享共享后端服务的状态.
  • 将持久性代码放入单独的WAR并使用REST调用(至少在我们的情况下)对开发人员来说是非常不方便的,并且与直接调用共享bean相比,增加了到达数据库的路径长度.


Jef*_* DQ 12

像tomcat这样的Web应用程序容器的一般用途是每个应用程序都能够独立运行(这样您就可以在不影响其他应用程序的情况下停止和启动各个应用程序),这意味着可能需要花费很多精力才能将其开发到阻止你这样做.所以,即使你发现了一个漏洞,我建议不要使用它,除非建议或至少由设计师批准.

我建议你开始寻找其他解决方案.例如:

  • 你真的需要共享对象实例吗?如果它们是无状态的,您可能不需要,并且您只需在每个应用程序中运行上下文的副本.
  • 您是否可以将您尝试共享的代码分成第三个暴露休息服务的WAR?或者也许现有的WAR中的一个可以作为服务.


小智 6

我认为你应该查看一篇信息丰富的博客文章:在多战Spring应用程序中使用共享的父应用程序上下文