当使用@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?
可以在生产环境中像这样实现它吗?
绝对。 否则,他们不存在。