我正在研究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();
}
}
使用此实现,查找工作正常,但函数暂停/冻结线程,因为容器尚未准备好返回NOT代理实现,但整个EJB和函数无法执行。
当调用构造函数时,bean尚未初始化并且没有注入依赖项?只返回代理但它尚不可用,无法从池中检索整个EJB?
答案 0 :(得分:2)
来自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上的元数据注释指定 class或部署描述符。这包括豆子 SessionContext,如果适用的话。第三,容器调用 PostConstruct bean的生命周期回调拦截器方法,如果 任何。如果会话bean是,则下面描述的附加步骤适用 通过EJB 2.1客户端视图API调用。
特别是,此时任何依赖注入字段(即使用EJB注释)都将为null。使用InitialContext
您已绕过此约束,这是意外行为的原因。
根据您所描述的行为,听起来好像您的容器首先构建bean,因此{I}尝试调用它时EjbInjectedLocal
bean不可用。我对它的死锁感到惊讶,但并不觉得它没有工作。在其他容器上尝试相同的实验并看看你是否得到相同的结果会很有趣。
答案 1 :(得分:0)
只返回代理但它尚不可用,无法从池中检索整个EJB?
这是对的。你只是在这里陷入困境。