我应用的结构是这样的:
client | ----- 网络边界 ----- | +--> sessionfacade(sessionbean)(stateful)(remote) | +--> util(sessionbean)(stateless)(local) | +--> entity(entitybean)(local){CMP/CMR}
|
在 util 层次上,我采用 stateless sessionbean 来服务多个 sessionfacade 会话用到的通用功能。为提高性能,我要在这个层次提供 cache 能力,比方,缓存部分查询结果,我的办法是存一个 MAP 实例进行全局 cache。显然,这个缓存功能的入口应该是在多个 util 的实例之间共享的,也就是说,应该是一个 singleton 对象。但,我似乎无法在 EJB 环境下实现它。至少在我搭建的 apusic 测试环境中是这样。我尝试过这样几种方法:
1.static 成员变量
示例代码:
private static Map cache = new Hashtable();
|
似乎并不管用,而且,EJB的编程限制中提到因该避免使用非 final 的 static 变量(既使加了 final 还是会再第二个会话中丢失)。2.标准的 singleton 模式
示例代码:
public class Singleton {
private Singleton() {}
// singleton logic private static Singleton singleton; public static Singleton getInstance(){ if(singleton == null) singleton = new Singleton(); return instance; }
}
|
似乎也不管用,或者因为它也是由 static 的一个对象实现的,或许在多 classloader 的环境下,就会失去唯一性。3.在系统 JNDI 中保存公用对象
private Map getCache() { Map cache = null; try { cache = (Map) jndiUtil.get(classname + ".cache"); if (cache == null) { cache = new Hashtable(); jndiUtil.set(classname + ".cache", cache); } } catch (Exception e) { log.debug( "AuthManagerBean.init()" , e ); } log.debug( "cache:" + cache ); return cache; }
|
这是某篇文章中推荐的方法,但,似乎也不管用(或许我的方法不对?)给我的感觉是在 session facade 的一个会话退出之后,这个 stateless sessionbean (以及它所创建的JNDI context)也被连带的 renew 了。
有那位大侠曾经在应用中碰见过类似的场景?请不吝指教解决方法,解我于倒悬。(如能给出示例代码,更将不胜感激)