1

我正在尝试在 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 共享静态单例吗?最后我决定使用数据库表,但我仍在考虑这个问题。

感谢您的回复。

4

5 回答 5

4

据我记得,您不能确定无状态 bean 是否足够全局,可以让您将数据保存在静态字段中。有几个缓存框架可以帮助您解决这个问题。也许内存缓存

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

在 EJB 中不允许使用非最终静态类字段,因为此类字段使企业 bean 难以或无法分发

于 2009-01-30T22:49:44.233 回答
3

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

于 2009-01-30T23:39:04.897 回答
2
@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 分布的注意事项适用于静态变量。但是,如果您不进行集群,它们几乎不适用于您,因此在这个级别上,静态是“好的”。

您将遇到同步问题。

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

您也可以自己管理同步,但您不应该在 EJB 方法级别这样做,而是拥有一个同步的 Cache 对象(与通用 HashMap 相比)可能会更好。

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

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

于 2009-01-30T23:33:40.213 回答
1

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

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

于 2009-01-30T22:51:02.343 回答
1

我知道这篇文章是不久前的,但似乎有一个新的 Singleton Bean 可以满足原始问题所针对的缓存需求:

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

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

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

于 2011-08-09T23:41:18.677 回答