Seam Component.getInstance() 和 JNDI 上下文查找的区别

3

我有一个带有以下注释的有状态会话bean:

@Stateful
@Name("fooBar")
public class FooBarAction implements FooBar {

我注意到有两种方法可以获得我的FooBar实例: Seam查找:
Component.getInstance(FooBarAction.class);

JNDI查找:

(new InitialContext()).lookup("MYAPP/FooBarAction/local");

当我使用JNDI查找时,每次执行查找时都会创建一个新的FooBar实例。默认构造函数被调用,并使用setter方法将我的SFSB的状态(属性)带回来。
当我使用Seam查找时,不会调用默认构造函数也不会调用setter方法。我只有这个实例。与之前的查找相同的实例。
那么区别在哪里?最佳使用方式是什么?
1个回答

2

来自文档:此方法返回指定组件的单例,因此连续两次使用相同的组件名称调用它将返回该组件的相同实例。


"Petr Mensik": 是的,谢谢。但是为什么JNDI查找也没有返回单例?它正在创建一个新的SFSB。 - Jochen Hebbrecht
因为容器需要始终返回新实例。原因是Statefull bean不是池化的,而是根据用户请求创建的。 - Petr Mensik
@“Petr Mensik”:Seam会创建一个SFSB,并将其放入池/容器中。如果我们调用它,它将从池中获取SFSB。JNDI查找仅在EJB缓存中存储SFSB的属性。如果我们调用SFSB,则会创建一个新实例,并使用setters方法从EJB缓存中检索属性并导入实例中。我说得对吗? - Jochen Hebbrecht
@PetrMensik 这不正确。没有所谓的 EJB 缓存。当您从 JNDI 查找 SFSB 时,您会获得一个全新干净的实例。它不会自动获得状态,因为这取决于客户端的操作。想一想:对于100个客户端,容器怎么知道恢复哪个状态?如果客户端持有一个实例(代理)并且一段时间内不使用它,容器可能会将该 Bean 挂起。如果客户端再次使用该实例,则该特定实例的状态将被恢复。如果同一客户端再次进行 JNDI 查找,则会获得一个完全不同的实例。 - Mike Braun
@MikeBraun:好的,通过使用JNDI,我的SFSB会创建一个新实例和代理。容器如何注入私有属性的数据?如果它创建了一个新实例,那么它在哪里存储这些属性? - Jochen Hebbrecht
显示剩余8条评论

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