当使用@EJB时,每个托管bean是否都有自己的@EJB实例? [英] When using @EJB, does each managed bean get its own @EJB instance?

查看:213
本文介绍了当使用@EJB时,每个托管bean是否都有自己的@EJB实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using JSF 2.2 for a web project and I am implementing the login page now.

我有一个 login.xhtml ,作为视图 bean被称为 UserLoginView

这个bean有一个 EJB 属性bean 私人UserService userService (如 here )。

I have a login.xhtml that serves as the view, and a backing bean called UserLoginView.
This bean has an EJB property bean private UserService userService (as shown here).

这是否意味着每个新的 UserLoginView 获取一个新的 UserService

Does this mean that each new UserLoginView gets a new instance of UserService?

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

Is OK to implement it like this in a production environment?

推荐答案


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

没有。给定的 UserService 是一个 @Stateless EJB。 @Stateless EJB被合并并注入为由容器自动生成的可序列化代理。当EJB发生异常时,堆栈跟踪就是证明这一点。您可以在支持bean方法和EJB方法之间看到额外的层。

Nope. The given UserService is a @Stateless EJB. @Stateless EJBs are pooled and injected as serializable proxies autogenerated by the container. Among others the stack trace when an exception occurs from an EJB is evidence for this. You see extra layers between the backing bean method and the EJB method.

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

The autogenerated proxy class for a @Stateless EJB looks roughly like this (in reality it's more complex, e.g. DB transaction also needs to be obtained, started and committed here):

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中。

Do you see it? It just grabs an available instance from the EJB pool and then delegates the method call to it and finally releases it to the pool for future reuse. It's exactly this proxy instance which is actually being injected in your JSF managed bean.

CDI也以这种方式工作。这就是为什么CDI可能会在更广泛的范围内的bean中注入一个较窄范围的bean,并且仍然可以使其按照意图工作。 JSF的 @ManagedBean 注入实际实例,因此它不起作用。如果JSF还使用通过 FacesContext 并且委托给它的当前bean实例的代理,那么这将是有效的。

CDI works also this way by the way. That's exactly why it's with CDI possible to inject a bean of a narrower scope in a bean of a wider scope and still get it to work as intented. JSF's @ManagedBean injects the actual instance and therefore it doesn't work that way. It would have worked if JSF also used proxies which actually grabbed the current bean instance via FacesContext and delegated to it.

只有 @Stateful EJB实际上与客户端的生命周期相关。在被管理bean作为客户端的情况下,它确实会获得自己的实例。另请参见 JSF请求范围bean在每个请求中都会重新创建新的有状态会话bean?

Only @Stateful EJBs are actually tied to the lifetime of the client. In case of managed bean as client, it would indeed get "its own" instance. See also JSF request scoped bean keeps recreating new Stateful session beans on every request?


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

绝对。否则他们不存在。

Absolutely. Otherwise they didn't exist.

这篇关于当使用@EJB时,每个托管bean是否都有自己的@EJB实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆