使用@EJB时,每个托管bean是否都有自己的@EJB实例?

时间:2014-08-26 20:08:49

标签: jsf java-ee ejb jsf-2.2

我正在使用JSF 2.2进行Web项目,现在我正在实现登录页面。

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

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

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

1 个答案:

答案 0 :(得分:17)

  

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

不。给定的UserService@Stateless EJB。 @Stateless将EJB汇集并注入由容器自动生成的可序列化代理。其中,EJB发生异常时的堆栈跟踪就是证据。您可以在backing bean方法和EJB方法之间看到额外的层。

@Stateless 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注入实际的实例,因此它不会那样工作。如果JSF也使用通过FacesContext实际获取当前bean实例并委托给它的代理,那就行了。

只有@Stateful个EJB实际上与客户端的生命周期相关联。如果托管bean作为客户端,它确实会得到自己的"实例。另请参阅JSF request scoped bean keeps recreating new Stateful session beans on every request?


  

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

绝对。否则他们就不存在了。