将EJB作为实例变量注入servlet是否安全?

Bre*_*nah 12 servlets code-injection ejb-3.0

我们都知道,在Web层中,可能只存在给定Servlet的单个实例,该实例为多个请求提供服务.这可能导致实例变量中的线程问题.

我的问题是,使用@EJB注释将EJB作为实例变量注入servlet是否安全?

在假设EJB的同一实例同时为多个请求提供服务的情况下,我的初衷是不.看起来这也是许多其他程序员的本能:不要注入servlet

但是我得出了错误的结论.显然,注入servlet的是一个代理,在容器下,容器实际上是用不同的实例为每个请求服务并保持线程安全吗?正如这个论坛所建议的那样:注入servlet

似乎存在很多相互矛盾的观点.哪个是对的???

小智 11

只要EJB是无状态的,将Servlet中的EJB作为Servlet实例变量注入是安全的.你必须永远不要在Servlet中注入有状态Bean.

您必须实现EJB无状态,因为它不包含任何本身具有有状态值的实例变量(如持久性上下文).如果需要使用持久性上下文,那么必须在EJB的方法中获取它的实例.您可以通过将PersistenceContextFactory作为EJB实例变量来实现,然后在EJB的方法中从Factory获取实体管理器的实例.

PersistenceContextFactory是线程安全的,因此可以将其注入实例变量中.

只要您遵守上述规则,在Servlet中注入无状态Bean应该是线程安全的


top*_*hef 3

您的参考文献“不要注入 servlet”没有提及有关 ejbs 或 @ejb 注释的内容。它讨论非线程安全对象,例如 PersistenceContext。

根据 EJB 规范,您可以从各种远程客户端(包括 servlet)访问 ejb(EJB 3.0 规范 (JSR-220) - 第 3.1 节)。使用@EJB注释注入ejb是一种通过依赖注入(第3.4.1节)获取EJB接口的方法,它是在JNDI命名空间中查找ejb对象的替代方法。因此,对于获得的 EJB,@EJB 注释没有什么特别之处。

因此,根据 EJB 3.0 规范,使用 @EJB 注释从 servlet 获取 ejb 是一种标准做法。