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

时间:2008-11-06 09:54:27

标签: java hibernate spring jboss ejb-3.0

我们目前有一个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之上使用一堆业务对象。

致以最诚挚的问候,

尼尔斯

9 个答案:

答案 0 :(得分:5)

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,但我不是春天的人,所以我不能谈论细节。

答案 1 :(得分:4)

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

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

答案 2 :(得分:3)

Terracotta可能非常合适(披露:我是Terracotta的开发人员)。 Terracotta透明地在JVM级别集群Java对象,并与Spring和Hibernate集成。它是免费和开源的。

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

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

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

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

请在此处查看:http://reference.terracotta.org/examinator

答案 5 :(得分:1)

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

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

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

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

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

答案 6 :(得分:1)

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

答案 7 :(得分:0)

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

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

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

答案 8 :(得分:-1)

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

相关问题