通过EJB共享静态单例

时间:2009-01-30 22:35:34

标签: java java-ee static singleton ejb

我正在尝试在Web服务中创建缓存。为此,我创建了一个新的无状态Bean,以便为其他无状态bean提供此缓存。此缓存只是一个静态ConcurrentMap,其中MyObject是一个POJO。 问题是它似乎有不同的缓存对象。一个用于客户端bean,另一个用于本地。

-CacheService
-CacheServiceBean
  -getMyObject()
  -insertMyObject(MyObject)
  -size()

-SomeOtherBean
 cache = jndiLookup(CacheService)
 cache.insertMyObject(x)
 cache.size() -> 1

在这个赋值之后,如果我从CacheServiceBean中调用cache.size,我得到0。 甚至可以通过bean共享静态单例吗?最后我决定使用数据库表,但我仍在考虑这个问题。

感谢您的回复。

5 个答案:

答案 0 :(得分:4)

据我所知,你无法确定无状态bean是否足够全局,可以将数据保存在静态字段中。有几个缓存框架可以帮助您解决这个问题。也许memcache

编辑: http://java.sun.com/blueprints/qanda/ejb_tier/restrictions.html#static_fields说:

  

非最终静态类字段   EJB中不允许这样的字段   使企业bean变得困难或者   不可能分发

答案 1 :(得分:3)

从表面上看,这似乎是一个矛盾,因为缓存几乎肯定是我不会认为是无状态的,至少在一般意义上是这样。

答案 2 :(得分:1)

使用无状态bean时,您无法控制它们拥有多少个实例(由您的应用服务器来处理)。您可以从另一个bean获得输出,而不是从客户端查找的输出。你在日志中打印过了吗?在这种情况下,您可能应该看到多个输出。关键是当你通过jndi查找无状态bean时,你无法知道你得到了哪个实例(你得到一个)。 而且,你没有状态,所以我不知道这是否是缓存的最佳选择。

通过静态单例,我想你的意思是单个对象? 是的,通过许多bean访问单例不应该是一个问题。但请记住您可能会遇到的并发问题。应用服务器(一般来说是bean)从你身上抽象了很多。

答案 3 :(得分:1)

@Stateless
public class CacheSessionBean implements CacheSessionLocal {
    private static Map<String, Object> cacheMap = new HashMap<String, Object>();

    public Object getCache(String key) {
        return cacheMap.get(key);
    }

    public void putCache(String key, Object o) {
        cacheMap.put(key, o);
    }
}

关于群集中EJB分布的警告适用于静态变量。但是,如果你没有聚类,它们几乎不适用于你,所以静态在这个级别上是“okey dokey”。

您将遇到同步问题。

缓解这种情况的一种方法是将容器配置为仅创建和汇集CacheSession bean的单个实例,然后容器将为您管理该同步。

您也可以自己管理同步,但是不应该在EJB方法级别执行此操作,而是使用同步的Cache对象(例如,通用HashMap)可能会更好。

但关键是,在这一点上,静态变量只是静态变量。

理论上,您需要了解会话Bean的容器生命周期(因为它可能会释放所有实例,因此实际的bean类可能符合GC的条件,因此可能会丢失任何静态数据)。但是,在实践中,如果该服务很受欢迎,则不太可能发生这种情况。但是,仅供参考,它可能会发生。

答案 4 :(得分:1)

我知道这篇文章不久前了,但似乎有一个新的Singleton Bean可以满足原始问题的目标:

http://download.oracle.com/javaee/6/tutorial/doc/gipjg.html

  

Singleton会话bean提供与无状态会话bean类似的功能,但与它们的不同之处在于每个应用程序只有一个单独的会话bean,而不是无状态会话bean池,其中任何一个都可以响应客户端请求。与无状态会话bean一样,单例会话bean可以实现Web服务端点。

我尝试过创建一个并从WebService / Stateless bean引用它。像宣传的那样工作。