When using @EJB, does each managed bean get its own @EJB instance?

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

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).

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

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


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

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.

The autogenerated proxy class for a @Stateless EJB looks roughly like this (in reality it's more complex, eg 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;
    }

    // ...
}

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 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.

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?


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

Absolutely. Otherwise they didn't exist.

链接地址: http://www.djcxy.com/p/50216.html

上一篇: Field.get(obj)返回注入的CDI托管bean上的所有空值,而手动调用getter返回正确的值

下一篇: 当使用@EJB时,每个托管bean都得到它自己的@EJB实例吗?