当前位置: 技术问答>java相关
EJB环境下的Singleton?
来源: 互联网 发布时间:2017-03-08
本文导语: 我应用的结构是这样的: client | ----- 网络边界 ----- | +--> sessionfacade(sessionbean stateful remote) | +--> util(sessionbean stateless local ) | +--> entity(entitybean local) 即...
我应用的结构是这样的:
client
|
----- 网络边界 -----
|
+--> sessionfacade(sessionbean stateful remote)
|
+--> util(sessionbean stateless local )
|
+--> entity(entitybean local)
即,在作为 util 的层次上,我采用 stateless sessionbean 来服务多个 sessionfacade 会话的通用操作。我需要在 util 层次提供 cache 能力,比方,缓存部分查询结果之类,(存一个 MAP 实例进行全局 cache )。显然,这个缓存功能的入口应该是在多个 util 的实例之间共享的,也就是说,应该是一个 singleton 对象。但,我似乎无法在 EJB 环境下实现它。至少在我搭建的 apusic 测试环境中,是这样。我尝试过这样几种方法:
1.static成员变量(似乎不管用,而且,EJB的编程限制中提到因该避免使用非final的static变量)
2.标准的singleton模式(似乎也不管用,说到底,它也是由static的一个对象实现的,或许在多 classloader 的模式下,就失去唯一性了)
public class Singleton {
private Singleton() {}
// singleton logic
private static Singleton singleton;
public static Singleton getInstance(){
if(singleton == null) singleton = new Singleton();
return instance;
}
}
3.JNDI保存公用对象(似乎也不管用,或许我的方法不对?感觉是在一个回话退出之后,整个stateless sessionbean被renew了)
有那位大侠曾经试过在 stateless sessionbean 中碰见过类似情况的?请不吝指教解决方法,解我于倒悬。(如能给出实例代码,更将不胜感激)
client
|
----- 网络边界 -----
|
+--> sessionfacade(sessionbean stateful remote)
|
+--> util(sessionbean stateless local )
|
+--> entity(entitybean local)
即,在作为 util 的层次上,我采用 stateless sessionbean 来服务多个 sessionfacade 会话的通用操作。我需要在 util 层次提供 cache 能力,比方,缓存部分查询结果之类,(存一个 MAP 实例进行全局 cache )。显然,这个缓存功能的入口应该是在多个 util 的实例之间共享的,也就是说,应该是一个 singleton 对象。但,我似乎无法在 EJB 环境下实现它。至少在我搭建的 apusic 测试环境中,是这样。我尝试过这样几种方法:
1.static成员变量(似乎不管用,而且,EJB的编程限制中提到因该避免使用非final的static变量)
2.标准的singleton模式(似乎也不管用,说到底,它也是由static的一个对象实现的,或许在多 classloader 的模式下,就失去唯一性了)
public class Singleton {
private Singleton() {}
// singleton logic
private static Singleton singleton;
public static Singleton getInstance(){
if(singleton == null) singleton = new Singleton();
return instance;
}
}
3.JNDI保存公用对象(似乎也不管用,或许我的方法不对?感觉是在一个回话退出之后,整个stateless sessionbean被renew了)
有那位大侠曾经试过在 stateless sessionbean 中碰见过类似情况的?请不吝指教解决方法,解我于倒悬。(如能给出实例代码,更将不胜感激)
|
我觉得可以是这样
+--> sessionfacade(sessionbean stateful remote)
|
+--> util(sessionbean stateless local )
|
+--> javabean
|
+--> entity(entitybean local)
在stateless session和entity直接加个普通的javabean,用它来做缓存,用stateless session从entity把数据取出来放在javabean里,然后供stateful sessionbean来使用。
这样直接在javabean中加个static map或使用Singleton模式都可以了。
+--> sessionfacade(sessionbean stateful remote)
|
+--> util(sessionbean stateless local )
|
+--> javabean
|
+--> entity(entitybean local)
在stateless session和entity直接加个普通的javabean,用它来做缓存,用stateless session从entity把数据取出来放在javabean里,然后供stateful sessionbean来使用。
这样直接在javabean中加个static map或使用Singleton模式都可以了。
|
设计上好象有些问题:
util层用stateless不好,虽然避免了同步的问题,但是同时也失去了共享cached的能力。建议考虑stateful session bean,然后使用行集实现。(一点愚见)
util层用stateless不好,虽然避免了同步的问题,但是同时也失去了共享cached的能力。建议考虑stateful session bean,然后使用行集实现。(一点愚见)
|
刚刚看了ClassLoader的资料,我想singleton方案不行,是因为singleton是自己定义的类,classloader装载的时候不能确定由哪个层次的classloader装载。造成singleton实例的地址不一样。我想用static类的属性的方法也许可行。
public class Maps
{
public static Map map;
}
这样尽管classloader装载的时候Maps实例的地址不一样,但Map是标准类,是由SystemLoader装载的,那样就同一地址共享了。
水平有限,一点愚见,还请高手指教了。
public class Maps
{
public static Map map;
}
这样尽管classloader装载的时候Maps实例的地址不一样,但Map是标准类,是由SystemLoader装载的,那样就同一地址共享了。
水平有限,一点愚见,还请高手指教了。
|
试验的结果却是:另一次会话中,从 singleton 中取回的值完全是一个全新的值。
如果发生了更改,singleton的值当然是个全新的值了。singleton的实例是在多个会话中共享的。
如果发生了更改,singleton的值当然是个全新的值了。singleton的实例是在多个会话中共享的。