我正在研究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?
发布于 2015-07-11 13:31:00
来自EJB规范 (4.3.10.2):
由于无状态会话bean实例通常是池化的,因此客户端调用create方法的时间不需要与容器对无状态会话bean实例上PostConstruct/ejbCreate方法的调用有任何直接关系。
这是容器特有的行为,规范为实现者提供了一个创新的领域。实现甚至不需要使用bean池,任何延迟加载行为和准确的顺序bean都取决于容器,例如,它们为用户提供的配置:
configuration.html
关于实例化期间的调用顺序,规范(4.3.10节)说:
容器创建会话bean的实例,如下所示。首先,容器调用bean类的newInstance方法来创建一个新的会话bean实例。其次,容器执行bean类上的元数据注释或部署描述符指定的任何依赖项注入。如果适用的话,这包括bean的SessionContext。第三,容器调用bean的PostConstruct生命周期回调拦截器方法(如果有的话)。如果会话bean是通过EJB2.1客户端视图API调用的,则应用下面描述的其他步骤。
特别是,任何注入依赖项的字段(即使用EJB注释)此时都将为null。通过使用InitialContext,您已经绕过了这个约束,这就是意外行为的原因。
从您所描述的行为看,似乎您的容器首先构建了bean,因此在您试图调用它的时候,EjbInjectedLocal bean是不可用的。我很惊讶它死了,但并不奇怪它不起作用。在其他容器上尝试同样的实验,看看你是否得到同样的结果是很有趣的。
发布于 2015-07-04 13:36:49
只返回代理,但它尚未可用,无法从池中检索整个EJB?
是这样的。你只是把自己锁在这里。
https://stackoverflow.com/questions/31212489
复制相似问题