Java App Server中的Singleton ..这个想法有多糟糕?

时间:2009-03-18 23:13:59

标签: java java-ee jboss glassfish ejb-3.0

我目前正在研究一些在没有App Server的情况下开发的旧代码。它基本上是一堆带有输入接口和输出接口的“黑匣子代码”。 “黑匣子”类中的所有内容都是包含状态的静态数据结构,它们以定时间隔(每10秒)通过算法。黑盒子从主方法开始。

为了让自己保持这种状态,我正在考虑将“黑匣子”变成单身人士。基本上,任何想要访问黑盒内部逻辑的人都将获得相同的实例。这将允许我使用Message Driven bean作为黑盒子的输入,并使用某种JMS Publisher作为黑盒子的输出。

这个想法有多糟糕?有什么提示吗?

我遇到的一个主要问题是,“黑匣子”代码中可能存在我不知道的线程。

EJB中有“应用程序范围对象”这样的东西吗?

注意:我正在使用Glassfish

11 个答案:

答案 0 :(得分:15)

如果您使用简单的singelton,进入群集环境后将面临问题

在这种情况下,您在多个JVM上有多个类加载器,并且您的sinlgeton模式中断,因为您将拥有该类的多个实例。

应用服务器(可能在集群环境中)中单例的唯一可接受用途是当单例完全无状态时,仅用作访问全局数据/函数的便利。

我建议您检查应用服务器供应商针对此问题的解决方案。大多数(如果不是所有供应商)都会为您提供一些解决方案。

特别是对于您说您正在使用的Glassfish,请查看Singleton EJB support for Glassfish。它可能像添加单个注释一样简单。

答案 1 :(得分:3)

我会说创建一个单身实际上是唯一可行的想法。假设已知此“黑匣子”中的代码使用静态字段,则创建此外观的两个实例绝对不安全。否则结果是不可预测的。

答案 2 :(得分:2)

这听起来并不是一个坏主意,实际上听起来像是一个很好的主意。

从程序设计的角度来看:如果你的黑盒子在概念上是一个“对象”,其属性和方法对它们起作用,那么就把它变成一个对象,即使它们只有一个实例化了

答案 3 :(得分:2)

它应该有效,但是您可能需要处理一些问题。

正如你所提到的那样。 MDB在EJB容器中运行,您无法在其中创建自己的线程,因此您可能存在潜在问题。如果您可以访问实际代码(您听起来像这样),您可能需要进行一些重构以消除线程或使用“已批准”的线程方法。 CommonJ TimerManager可能会在您所述的情况下工作,因为它在一个间隔内执行某项任务。大多数应用服务器都有可用的实现(包括WAS和Weblogic)。

类加载 - 这取决于您的配置。如果在同一个EAR中从MDB创建和操作单例,你会没事的。单独的EAR将意味着不同的类加载器和您的Singleton的多个实例。在没有更多信息的情况下,无法评论这是否会成为您的问题。

答案 4 :(得分:2)

我错过了一点?你提到'黑盒代码'包含状态。 MDB可能限制为每个目标1个实例,但如果没有正确的配置,您最终会得到一些MDB。所有这些都与您的单个“黑匣子代码”实例一起使用。对我来说,似乎这不是一个好主意,因为一个bean将覆盖“黑盒子代码”状态,而另一个bean之前已创建了几个滴答。

答案 5 :(得分:1)

在我看来,更符合您要求的工件是JBoss MBean。 (如果你认为JBoss是AS候选者)。

Standard MBean Example

在JBoss群集的情况下,MBean也可以部署为单身人士。

Clustering with JBoss

我希望这对你有用。

拉​​法。

答案 6 :(得分:0)

修复代码以尽快摆脱静态。单身人士不是朝着正确方向迈出的一步 - 他们只会增加额外的误导。

答案 7 :(得分:0)

不要在州可能改变的地方使用单身人士。

公开你的黑盒子类的全局实例似乎不太可能。很多时候,单身人士似乎会让你的事情变得更容易,并且他们可以以某种方式,但它经常会回来咬你,你最终不得不重组你的大部分代码。

答案 8 :(得分:0)

在Web服务器世界中,对象可以作用于请求,会话或应用程序。也许你需要的是一个应用程序范围对象。

在文档中搜索“应用程序范围对象”或“应用程序生存期对象”。

答案 9 :(得分:0)

为什么不为空白框创建一个休息界面,让客户端进行http调用?

答案 10 :(得分:0)

IMO,拥有满足Singleton需求的EJB容器是个好主意。在Java EE 6中,在会话bean中放置@Singleton注释会为您提供一个命名的单例。