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

Chr*_*ris 11 jsf ejb java-ee jsf-2.2

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

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

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

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

Bal*_*usC 17

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

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

@StatelessEJB 的自动生成代理类看起来大致如此(实际上它更复杂,例如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;
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

你看到了吗?它只是从EJB池中获取可用实例,然后将方法调用委托给它,最后将其释放到池中以供将来重用.正是这个代理实例实际上是在你的JSF托管bean中注入的.

顺便说一句,CDI也是这样做的.这就是为什么CDI可以在更广泛的范围内的bean中注入更窄范围的bean,并且仍然可以按照意图使用它.JSF会@TransactionAttribute注入实际的实例,因此它不会那样工作.如果JSF也使用实际抓取当前bean实例@ManagedBean并委托给它的代理,那将会奏效.

只有FacesContextEJB实际上与客户端的生命周期相关联.如果托管bean作为客户端,它确实会得到"它自己的"实例.另请参阅JSF请求作用域bean继续在每个请求上重新创建新的有状态会话bean吗?


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

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