Jakarta ee EJB和静态字段

Jakarta ee EJB和静态字段,jakarta-ee,garbage-collection,ejb,classloader,static-variables,Jakarta Ee,Garbage Collection,Ejb,Classloader,Static Variables,我希望在无状态会话bean中有一个静态只读集合。理想情况下,只要应用程序正在运行,它将只初始化一次,并且对bean实例可用 假设此应用程序部署在具有多个服务器/JVM的集群环境中 据我所知,在第一种情况下,静态变量barList在容器创建bean的同时被初始化,并且与bean一样长(甚至更长?),并且在bean实例处于活动状态时不会有被垃圾收集的危险 在第二种情况下,当加载Foo类时,即bean的getBarList()方法执行时,barList被初始化。但当它被退回时会发生什么?它会在bean

我希望在无状态会话bean中有一个静态只读集合。理想情况下,只要应用程序正在运行,它将只初始化一次,并且对bean实例可用

假设此应用程序部署在具有多个服务器/JVM的集群环境中

据我所知,在第一种情况下,静态变量barList在容器创建bean的同时被初始化,并且与bean一样长(甚至更长?),并且在bean实例处于活动状态时不会有被垃圾收集的危险

在第二种情况下,当加载Foo类时,即bean的getBarList()方法执行时,barList被初始化。但当它被退回时会发生什么?它会在bean方法执行完毕后被销毁吗

案例1:

@Stateless
public class MrBean implements BeanInterface{

private static final List<Bar> barList;

static{

barList = new ArrayList<Bar>();

//create some bars, add them to the list

}

public List<Bar> getBarList(){

    return barList;
}
}
@无状态
公共类MrBean实现BeanInterface{
私有静态最终列表;
静止的{
barList=新的ArrayList();
//创建一些条,将它们添加到列表中
}
公共列表getBarList(){
返回条码列表;
}
}
案例2:

@Stateless
public class MrBean implements BeanInterface{

public List<Bar> getBarList (){

return Foo.barList;

}

}

public class Foo {

public static final List<Bar> barList;

static{ 

barList = new ArrayList<Bar>();

// create bars, add them to barList 

}

}
@无状态
公共类MrBean实现BeanInterface{
公共列表getBarList(){
返回Foo.barList;
}
}
公开课Foo{
公共静态最终列表;
静态{
barList=新的ArrayList();
//创建条形图,将其添加到条形图列表
}
}

我宁愿创建一个
@Singleton
bean,让它管理和服务列表。那么您有以下优势:

  • 对于整个应用程序,列表只初始化一次,并且不必是静态的,因此您符合EJB标准
  • EJB和列表可以在应用程序启动时初始化,而不是通过
    @startup
    @PostConstruct
    注释进行EJB初始化
  • 可以使用
    @Lock(READ)
    @Lock(WRITE)
    同时访问/操作列表
  • 您可以在一个EJB方法中使用@Observes模式来响应事件,并在需要时重新加载列表

  • 根据定义,您不能是“无状态”的,并且在静态字段中记住状态——事实上,它违反了标准。有关更多详细信息,请参阅。@stdunbar好的,我添加了“final”声明。好的,看起来在案例2中,只要有对barList的引用,barList就不会被垃圾收集,只要加载了Foo类,引用就在那里,除非类加载器本身被垃圾收集,并且非用户定义的类加载器不会被垃圾收集,否则Foo类不会被卸载。不过我最终还是用了一个普通的单身汉。