当使用@EJB时,每个托pipebean都得到它自己的@EJB实例吗?

我正在使用JSF 2.2作为Web项目,现在正在实现login页面。

我有一个作为视图login.xhtml和一个名为UserLoginView的支持bean。
这个bean有一个EJB属性bean private UserService userService (如下所示)。

这是否意味着每个新的UserLoginView都获得一个新的UserService实例?

可以在生产环境中像这样执行它吗?

这是否意味着每个新用户都获得一个新的实例UserService?

不。 给定的UserService@Stateless EJB。 @Stateless EJB被集成并注入为容器自动生成的可序列化代理。 除此之外,从EJB发生exception时的堆栈跟踪是证据。 您会在backing bean方法和EJB方法之间看到额外的层。

自动生成的@Stateless EJB的代理类看起来大致如此(实际上它更复杂,例如DB事务也需要在这里获得,启动和提交):

 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托pipebean的代理实例。

CDI也是这样工作的。 这就是为什么CDI可能在更广泛的bean中注入一个更窄范围的bean,并使其按照预期工作。 JSF的@ManagedBean注入实际的实例,因此它不会那样工作。 如果JSF也使用实际通过FacesContext获取当前bean实例并委托给它的代理的话,那就FacesContext了。

只有@Stateful EJB实际上绑定到客户端的生命周期。 在托pipebean作为客户端的情况下,它确实会得到“自己的”实例。 另请参见JSF请求作用域bean在每个请求上不断重新创build新的有状态会话Bean?


可以在生产环境中像这样实现它吗?

绝对。 否则,他们不存在。