【问题标题】:Inside EJB lookup: constructor, @PostConstruct内部 EJB 查找:构造函数,@PostConstruct
【发布时间】:2015-09-21 15:08:22
【问题描述】:

我正在研究 EJB 查找的洞察力,并试图了解容器和池的工作原理。我创建了一些测试应用程序,我将逐一解释。

第一个实现:在构造函数中查找

    @Stateless
    public class EjbTest {

    protected EjbInjectedLocal      ejbInjected;

    public EjbTest() {
            InitialContext ic = new InitialContext();
            ejbInjected = (EjbInjectedLocal)ic.lookup("java:comp/env/ejb/EjbInjected");
            ic.close();
    }

    public void test() {
        ejbInjected.callSomeMethod();
        return;
    }

}

在类构造函数内部执行注入(不好的做法),但一切正常。构造函数检索 EJB 的代理。当我调用方法test()时,它被正确执行了。

第二个实现:在@PostConstruct 内部查找

@Stateless
public class EjbTest {

    protected EjbInjectedLocal      ejbInjected;

    public EjbTest() {
    }

    @PostConstruct
    public start() {
            InitialContext ic = new InitialContext();
            ejbInjected = (EjbInjectedLocal)ic.lookup("java:comp/env/ejb/EjbInjected");
            ic.close();
    }

    public void test() {
        ejbInjected.callSomeMethod();
        return;
    }

}

与前面的示例一样,查找和方法测试都可以正常工作。

第三个实现:在构造函数内部查找和函数执行

@Stateless
public class EjbTest {

    protected EjbInjectedLocal      ejbInjected;

    public EjbTest() {
            InitialContext ic = new InitialContext();
            ejbInjected = (EjbInjectedLocal)ic.lookup("java:comp/env/ejb/EjbInjected");
            ejbInjected.callSomeMethod();
            ic.close();
    }

}

使用此实现,查找工作正常,但函数暂停/冻结线程,因为容器尚未准备好返回代理实现,但无法执行整个 EJB 和函数。

在调用构造函数时,bean还没有初始化,没有注入依赖?只返回代理但它还不可用并且无法从池中检索整个 EJB?

【问题讨论】:

    标签: jakarta-ee dependency-injection ejb ejb-3.0


    【解决方案1】:

    来自EJB specification (4.3.10.2):

    由于无状态会话 bean 实例通常是池化的,因此时间 客户端调用 create 方法不需要有任何 与容器调用的直接关系 无状态会话 bean 实例上的 PostConstruct/ejbCreate 方法。

    这是特定于容器的行为,规范将其作为实现者创新的区域开放。实现甚至不需要使用 bean 池,任何延迟加载行为和 bean 可用的确切顺序都取决于容器,它们为用户提供的配置也是如此,例如:

    http://docs.jboss.org/ejb3/docs/reference/1.0.7/html/SessionBean_and_MDB_configuration.html

    关于实例化期间的调用顺序,规范(第 4.3.10 节)说:

    容器创建会话 bean 的实例如下。第一的, 容器调用 bean 类的 newInstance 方法来创建一个 新的会话 bean 实例。二、容器执行任何 由 bean 上的元数据注释指定的依赖注入 类或部署描述符。这包括 bean 的 SessionContext(如果适用)。三、容器调用 bean 的 PostConstruct 生命周期回调拦截器方法,如果 任何。如果会话 bean 是,下面描述的附加步骤适用 通过 EJB 2.1 客户端视图 API 调用。

    特别是,此时任何依赖注入字段(即使用 EJB 注释)都将为空。通过使用InitialContext,您已经绕过了这个约束,这就是意外行为的原因。

    从您描述的行为看来,您的容器似乎首先构建了 bean,因此 EjbInjectedLocal bean 在您尝试调用它时不可用。我很惊讶它会死锁,但并不奇怪它没有工作。在其他容器上尝试相同的实验并查看是否得到相同的结果会很有趣。

    【讨论】:

      【解决方案2】:

      只返回代理但它还不可用并且无法从池中检索整个 EJB?

      没错。您只是在这里陷入僵局。

      【讨论】:

      • 方法 EjbTest() 被调用,EJB 代理可用,但 EjbTest EJB 尚未准备好,直到调用 @PostConstruct 方法(在类构造函数完成之后)。但是有几次第三个示例运行良好.. 任务完成只是时间问题?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 2013-05-23
      • 2016-03-11
      相关资源
      最近更新 更多