【问题标题】:EJB and static fieldsEJB 和静态字段
【发布时间】:2017-12-26 14:14:44
【问题描述】:

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

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

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

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

案例一:

@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;
}
}

案例 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 

}

}

【问题讨论】:

  • 根据定义,您不能“无状态”并记住静态字段中的状态 - 实际上,它违反了标准。有关详细信息,请参阅this answer
  • @stdunbar 好的,我添加了“最终”声明。
  • 好的,在案例 2 中,只要有对它的引用,barList 就不会被垃圾收集,只要加载了 Foo 类,引用就会在那里,并且 Foo除非类加载器本身被垃圾收集并且非用户定义的类加载器不会被垃圾收集,否则类不会被卸载。

标签: jakarta-ee garbage-collection ejb classloader static-variables


【解决方案1】:

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

  1. 整个应用程序的列表仅初始化一次,不必为static,因此符合 EJB 标准。
  2. 可以在应用程序启动时初始化 EJB 和列表,而不是通过 @Startup@PostConstruct 注释来初始化 EJB。
  3. 可以使用@Lock(READ)@Lock(WRITE)同时访问/操作列表。
  4. 您可以在您的 EJB 方法之一中使用 @Observes 模式来响应事件并在需要时重新加载列表

【讨论】:

  • 我使用的是 EJB 3.0,@Singleton 是在 EJB 3.1 中引入的。不过,我确实最终使用了普通的单身人士。
猜你喜欢
  • 2012-03-16
  • 1970-01-01
  • 2012-06-14
  • 2016-08-31
  • 2015-06-28
  • 2021-03-03
  • 1970-01-01
  • 2012-06-21
  • 2015-03-19
相关资源
最近更新 更多