我应用的结构是这样的:
client
|
----- 网络边界 -----
|
+--> sessionfacade(sessionbean)(stateful)(remote)
|
+--> util(sessionbean)(stateless)(local)
|
+--> entity(entitybean)(local){CMP/CMR}
<p>
|
在 util 层次上,我采用 stateless sessionbean 来服务多个 sessionfacade 会话用到的通用功能。为提高性能,我要在这个层次提供 cache 能力,比方,缓存部分查询结果,我的办法是存一个 MAP 实例进行全局 cache。显然,这个缓存功能的入口应该是在多个 util 的实例之间共享的,也就是说,应该是一个 singleton 对象。但,我似乎无法在 EJB 环境下实现它。至少在我搭建的 apusic 测试环境中是这样。我尝试过这样几种方法:
1.static 成员变量
示例代码:
private static Map cache = new Hashtable();
<p>
|
似乎并不管用,而且,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;
}
}
<p>
|
似乎也不管用,或者因为它也是由 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;
}
<p>
|
这是某篇文章中推荐的方法,但,似乎也不管用(或许我的方法不对?)给我的感觉是在 session facade 的一个会话退出之后,这个 stateless sessionbean (以及它所创建的JNDI context)也被连带的 renew 了。
有那位大侠曾经在应用中碰见过类似的场景?请不吝指教解决方法,解我于倒悬。(如能给出示例代码,更将不胜感激)