使用JBoss和Spring在Java Web应用程序之间共享业务对象实例的最佳方法是什么?

我们目前有一个Web应用程序加载一个Spring应用程序上下文,它实例化一堆业务对象,DAO对象和Hibernate。 我们希望与另一个Web应用程序共享此堆栈,以避免具有相同对象的多个实例。

我们研究了几种方法; 使用JMX或JNDI或使用EJB3公开对象。

不同的方法都有它们的问题,我们正在寻找一种轻量级的方法。

有关如何解决这个问题的任何建议?

编辑:我收到的评论要求我详细说明,所以这里有:

我们想要解决的主要问题是我们只想拥有一个Hibernate实例。 这是因为在运行使用相同数据源的多个客户端应用程序时,Hibernate的二级缓存失效问题。 此外,业务/ DAO / Hibernate堆栈的增长相当大,因此不重复它只是更有意义。

首先,我们试图了解如何单独将业务层暴露给其他Web应用程序,而Spring以少量XML的价格提供JMX包装。 但是,我们无法将JMX实体绑定到JNDI树,因此我们无法从Web应用程序中查找对象。

然后我们尝试将业务层直接绑定到JNDI。 尽管Spring没有为此提供任何方法,但使用JNDITemplate绑定它们也是微不足道的。 但这导致了几个新问题:1)安全管理器拒绝访问RMI类加载器,因此一旦我们尝试调用JNDI资源上的方法,客户端就失败了。 2)一旦安全问题得到解决,JBoss就抛出IllegalArgumentException:object不是声明类的实例。 一点阅读表明我们需要JNDI资源的存根实现,但这似乎有很多麻烦(也许Spring可以帮助我们?)

我们还没有看过EJB,但在前两次尝试之后,我想知道我们想要实现的目标是否完全可能。

总结一下我们想要实现的目标:一个JBoss实例,几个Web应用程序在DAO层和Hibernate之上使用一堆业务对象。

最好的祝福,

尼尔斯

Web应用程序是否部署在同一台服务器上?

我不能代表Spring,但使用Session Beans将业务逻辑转移到EJB层是很简单的。

申请组织是直截了当的。 Logic进入Session Beans,这些Session Beans作为带有ejb-jar.xml文件的Java EE工件捆绑在一个jar中(在EJB3中,这可能实际上是空的)。

然后将实体类捆绑到一个单独的jar文件中。

接下来,您将构建每个Web应用程序到自己的WAR文件中。

最后,所有的jar和wars都捆绑在一个Java EE EAR中,带有相关的application.xml文件(同样,这可能非常简单,只需枚举EAR中的jar)。

此EAR批量部署到应用服务器。

每个WAR实际上是独立的 – 它们自己的会话,有自己的上下文路径等。但它们共享公共EJB后端,所以你只有一个二级缓存。

您还使用本地引用并调用语义与EJB进行通信,因为它们位于同一服务器中。 这里不需要远程呼叫。

我认为这很好地解决了您所遇到的问题,并且在使用EJB 3的Java EE 5中它非常简单。

另外,正如我所理解的那样,你仍然可以在你的大部分工作中使用Spring,但我不是一个Spring人,所以我不能谈论细节。

spring的parentContext怎么样? 看看这篇文章:

http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html

兵马俑可能适合这里(披露:我是Terracotta的开发商)。 Terracotta透明地在JVM级别集群Java对象,并与Spring和Hibernate集成。 它是免费和开源的。

正如您所说,使用L2缓存的多个客户端Web应用程序的问题是保持这些缓存同步。 使用Terracotta,您可以集群单个Hibernate L2缓存。 每个客户端节点都使用该集群缓存的副本,并且Terracotta使其保持同步。 此链接解释更多。

至于您的业务对象,您可以使用Terracotta的Spring集成来集群bean – 每个Web应用程序可以共享集群bean实例,Terracotta可以透明地保持集群状态同步。

实际上,如果你想要一个轻量级的解决方案并且不需要事务或集群,只需使用Spring支持RMI。 它允许使用最新版本中的简单注释远程公开Spring bean。 请参见http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html 。

您应该看一下Terracotta参考Web应用程序 – Examinator。 它有你正在寻找的大多数组件 – 它有Hibernate,JPA和带有MySQL后端的Spring。

它经过预先调整,可扩展到16个节点,20k并发用户。

在这里查看: http : //reference.terracotta.org/examinator

到目前为止,谢谢你的答案。 我们仍然不在那里,但我们现在尝试了一些事情并且更清楚地看待事情。 这是一个简短的更新:

似乎最可行的解决方案是EJB。 但是,这将需要对我们的代码进行一些更改,因此我们现在不会完全实现该解决方案。 我几乎感到惊讶的是,我们无法找到一些Springfunction来帮助我们。

我们还尝试了JNDI路由,最终需要所有共享接口的存根。 考虑到一切都在同一台服务器上,这感觉很麻烦。

昨天,我们与JMX进行了一次小小的突破。 虽然JMX肯定不适合这种用途,但我们已经certificate它可以完成 – 没有代码更改和最少量的XML(对于MBeanExporter和MBeanProxyFactoryBean非常感谢Spring)。 这种方法的主要缺点是性能和我们的域类必须通过JBoss的server / lib文件夹共享的事实。 即,我们必须从WAR中删除一些依赖项并将它们移动到server / lib,否则当业务层从我们自己的域模型返回对象时,我们会得到ClassCastException。 我完全理解为什么会这样,但它并不适合我们想要实现的目标。

我认为是时候进行一些更新,因为看起来最好的解决方案需要一些时间才能实现。 一旦我们完成了这项工作,我会在这里发布我们的研究结果。

Spring确实有一个你可能感兴趣的集成点: EJB 3 injection nterceptor 。 这使您可以从EJB访问spring bean。

我不确定你要解决的问题; 在每天结束时,每个jvm将具有对象的复制实例,或者表示存在于另一(逻辑)服务器上的对象的存根。

您可以设置第三个“业务逻辑”服务器,该服务器具有您的两个Web应用程序可以调用的远程API。 典型的解决方案是使用EJB,但我认为spring在其堆栈中内置了远程选项。

另一种选择是使用某种forms的共享缓存架构…它将同步服务器之间的对象更改,但您仍然有两组实例。

看看JBossCache 。 它允许您在多个JVM实例(相同的框或不同的实例)之间轻松共享/复制数据映射。 它易于使用,并具有许多线路级协议选项(TCP,UDP组播等)。