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

发布于 2024-07-14 19:33:00 字数 561 浏览 9 评论 0原文

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

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

我最初的直觉是否定的,因为假设 EJB 的同一实例将同时服务多个请求。 这似乎也是许多其他程序员的本能: 不要注入 servlet

但是我得出了错误的结论。 显然,注入到 servlet 中的是代理,在幕后容器是否实际上使用不同的实例为每个请求提供服务并维护线程安全? 正如该论坛建议的那样: Do 注入 servlet

那里似乎有很多相互矛盾的意见。 哪个是对的???

We all know that in the web tier there is the possibility that only a single instance of a given Servlet exists which services multiple requests. This can lead to threading issues in instance variables.

My question is, is it safe to inject an EJB using the @EJB annotation into a servlet as an instance variable?

My initial instinct would be no, under the assumption that the same instance of the EJB would service multiple requests at the same time. It would seem that this would also be the instinct of a number of other programmers: Don't inject to servlets

However have I jumped to the wrong conclusion. Clearly what is injected into the servlet is a proxy, under the hood does the container actually service each request with a different instance and maintain thread safety? As this forum would suggest: Do inject to servlets

There seems to be a lot of conflicting opinions. WHICH IS CORRECT???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你げ笑在眉眼 2024-07-21 19:33:00

只要 EJB 是无状态的,将 EJB 作为 Servlet 实例变量注入 Servlet 中就是安全的。 绝对不能在 Servlet 中注入 Stateful Bean。

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

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

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

It is safe to inject an EJB in a Servlet as a Servlet instance variable, as long as the EJB is Stateless. You MUST NEVER inject a Stateful Bean in a Servlet.

You must implement your EJB stateless in that it doesn't hold any instance variable which itself holds a stateful value (like Persistence Context). If you need to use the persistence context, then you must get an instance of it IN the methods of the EJB. You can do that by having a PersistenceContextFactory as a EJB instance Variable and then you get an instance of the entity manager from the Factory in the method of the EJB.

The PersistenceContextFactory is thread-safe, thus it can be injected in an instance variable.

As long as you comply to the above mentioned rules, it should be thread-safe to inject a Stateless Bean in a Servlet

浮世清欢 2024-07-21 19:33:00

您的参考文献“不要注入 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 是一种标准做法。

Your reference "Don't inject to servlets" mentions nothing about ejbs or @ejb annotation. It talks about not thread safe objects such as PersistenceContext.

Per EJB spec you can access ejbs from variety of remote clients including servlets (EJB 3.0 Specification (JSR-220) - Section 3.1). Injecting ejb using @EJB annotation is a method of obtaining EJB interface via dependency injection (section 3.4.1) which is alternative to looking up ejb objects in the JNDI namespace. So there is nothing special about @EJB annotation with respect to EJBs obtained.

So, based on EJB 3.0 Spec, it's a standard practice to obtain ejbs from servlets using @EJB annotation.

故人如初 2024-07-21 19:33:00

这是一个混合包。

无状态会话 Bean 可以被注入并且是安全的。 这是因为即使使用存根的单个实例,对方法的访问也将由容器序列化。

我认为 inferreddesign 所说的不正确。 无状态会话 bean 是否使用持久性上下文并不重要。 只有一个调用者会同时访问单个 bean 实例,因此即使持久性上下文不是线程安全的,EJB 也会防止对其进行多次访问。 可以想象每个会话 bean 方法都应用了同步关键字。

我认为在 Servlet 中注入 EJB 的主要问题是性能。 当多个请求排队等待为其执行会话 bean 方法时,单个存根实例将成为主要的争用区域。

It's a mixed bag.

Stateless session beans may be injected and are safe. This is because even if a single instance of a stub is used, access to the methods will be serialized by the container.

I think what inferreddesign says is not true. It doesn't matter if the stateless session bean uses a persistence context. Only one caller will ever access a single bean instance at the same time, so even though the persistence context is not thread safe, the EJB guards against multiple access to it. Think of it as if every session bean method has the synchronized keyword applied to it.

The main problem with injecting an EJB in a Servlet I think is performance. The single stub instance will become a major area of contention when multiple requests are queuing up while waiting for a session bean method to be executed for them.

北城孤痞 2024-07-21 19:33:00

我认为简单的答案是不能保证它是安全的。

原因是 EJB 规范中没有明确规定 EJB 主接口必须是线程安全的。 该规范仅概述了服务器端部分的行为。 您可能会发现客户端框架实际上是线程安全的,但您需要查看您正在使用的库如何实现它们。 注释部分将扩展为服务定位器,因此不会为您购买任何东西。

I think the simple answer is that you aren't guaranteed that it is safe.

The reason for this is that there is nothing explicit in the EJB specification that says EJB home interfaces have to be thread safe. The spec outlines the behaviour of the server side part only. What you will probably find is that the client skeletons are actually thread safe but you would need to look at how they are implemented by the library you are using. The annotation part will just expand into a service locator so that doesn't buy you anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文