我正在将 JSF 2.2 用于 Web 项目,并且现在正在实现登录页面。
我有一个login.xhtml
作为view,和一个名为的支持 beanUserLoginView
.
这种豆子有一个EJB
属性beanprivate UserService userService
(如图所示here).
这是否意味着每个新UserLoginView
得到一个新实例UserService
?
在生产环境中这样实现可以吗?
这是否意味着每个新的 UserLoginView 都会获得一个新的 UserService 实例?
没有。给定的UserService
is a @Stateless
EJB. @Stateless
EJB 作为容器自动生成的可序列化代理进行池化和注入。其中,EJB 发生异常时的堆栈跟踪就是这一点的证据。您会看到支持 bean 方法和 EJB 方法之间有额外的层。
自动生成的代理类@Stateless
EJB看起来大致是这样的(实际上更复杂,例如DB事务也需要在这里获取、启动和提交,具体取决于@TransactionAttribute
EJB 类和/或方法):
public class UserServiceProxy extends UserService implements Serializable {
public User find(Long id) {
UserService instance = getAnAvailableInstanceFromPool();
User result = instance.find(id);
releaseInstanceToPool(instance);
return result;
}
public Long save(User user) {
UserService instance = getAnAvailableInstanceFromPool();
Long result = instance.save(user);
releaseInstanceToPool(instance);
return result;
}
// ...
}
你看到了吗?它只是从 EJB 池中获取一个可用实例,然后将方法调用委托给它,最后将其释放到池中以供将来重用。实际上,正是这个代理实例被注入到您的 JSF 托管 bean 中。
顺便说一下,CDI 也是这样工作的。这正是为什么使用 CDI 可以将范围较窄的 Bean 注入范围较广的 Bean 中,并且仍然可以使其按预期工作。 JSF的@ManagedBean
注入actual实例,因此它不会那样工作。如果 JSF 也使用代理来实际获取当前 bean 实例,那么它就会起作用FacesContext
并委托给它。
Only @Stateful
EJB 实际上与客户端的生命周期相关。如果托管 bean 作为客户端,它确实会获得“它自己的”实例。也可以看看JSF 请求作用域 bean 会在每个请求上不断重新创建新的有状态会话 bean?
And @Singleton
EJB 池中基本上最多有一个实例。因此每个客户端将始终获得相同的实例。
在生产环境中这样实现可以吗?
绝对地。否则它们就不存在。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)