EJB无状态初始化模式

6
我有一个EJB Stateless Session Bean,需要满足以下要求:
  1. 在启动时初始化这个Stateless EJB
  2. 初始化代码应该对数据库进行事务访问
问题是:
  1. @Startup仅适用于@Singleton EJBs
  2. @PostConstruct注释(至少在Websphere上)此时没有事务上下文,因此初始化代码会出错!
可能的解决方案是:
  1. 使用Java EE计时器,但它似乎被设计用于定期执行。我只想在时间零执行一次。
  2. 使用@Singleton + @Startup EJB仅用于初始化目的,并将此singleton EJB注入依赖的Stateless EJB中。
问题是:
  1. 有人能解释一下Stateless EJB应该如何初始化吗?还是说这没有意义?(我的意思是,Stateless EJB不应该具有初始化状态吗?)
  2. 有没有模式表明使用辅助EJB @Singleton和@Startup是一个好主意?

我很惊讶Websphere没有为@PostConstruct提供TX上下文,因为这是EJB 3.1规范要求的。您使用的是哪个版本的Websphere? - NBW
2
事务上下文并非规范要求。请查看以下链接:http://docs.oracle.com/javaee/6/tutorial/doc/gkedm.html 和 https://blogs.oracle.com/arungupta/entry/what_s_new_in_ejb - Andrés Oviedo
抱歉,我误读了您的帖子,我以为您在谈论Websphere和@Singletons,但是重新阅读后,我可以看到您使用2)来指代您最初的无状态情况。 - NBW
3个回答

4

最终我选择了:

  • EJB @Stateless -- 引用 --> EJB @Singleton(带有 @Startup

这样,我就可以初始化为处理请求所必需的(共享和只读)状态或上下文。


2
初始化一个无状态的EJB没有意义,因为这是Java EE容器的工作。此外,Java EE 6本身就提供了IOC模式。IOC基本上意味着隐藏注入资源初始化过程。
您的第二个解决方案是正确的,因为您需要事务性访问。
然后您需要考虑两种情况/状态:
a. 单例成功启动
b. 单例启动失败
换句话说,您确定您的(1.)语句是正确的,还是您可能会将其解释为懒惰初始化模式?
由于@startup发生在应用程序启动时,也许具有延迟初始化激活的单例状态也符合您的需求?

1
初始化代码应该对数据库进行事务访问。 我不清楚数据库访问的目的,但是如果您需要获取一些数据并将其存储为无状态会话bean属性,请注意以下内容: - 这些信息将在每个无状态实例中复制。 - 每次创建新的bean实例时,都会执行数据库查询。 - 在某些情况下,很难确定所有bean实例具有相同的状态。
我不知道模式的名称,但是将信息存储在单例会话bean中并将其注入到无状态bean中是一个很好的解决方案。即使单例bean可以处理同时请求,因此它不会成为瓶颈。这还允许您以更一致的方式管理可能的信息更改。

1
每当创建一个新的Bean实例时,您将执行数据库查询。在此情况下,JBoss在其无限的智慧中已决定完全不再池化无状态会话Bean。因此,在最新版本的JBoss中调用无状态Bean时,都会构造一个新的Bean,因此上述查询将被重复执行。您可以通过特定于JBoss的设置重新启动池化。 - Arjan Tijms
@gabriel-aramburu 谢谢您的回答。它们非常有用! - Andrés Oviedo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接