2

我在 Adam Bien 的 JavaEE night hacks 书中读到,虽然在 EJB 容器上禁止创建线程,但对于 Web 容器却不是这样。他实际上在他的 X 射线探测器中创建了一个线程池执行器,该探测器在 Tomcat 上运行。

我现在有点困惑。虽然我遇到了必须在 EE 应用程序中进行手动线程池管理的情况,但我可以理解为什么在 JavaEE 容器中手动创建线程是个坏主意。但是,当您可以将大部分 EJB 部署到其中一个时,我不明白 EJB 容器和 Web 容器在线程创建方面的区别。如果在 Web 容器中生成线程的会话 bean 没有任何问题,那么将相同的会话 bean 部署到 EJB 容器会导致什么问题?

4

3 回答 3

10

这就是 Java EE 的“企业”部分与现实世界相遇的地方。

使用“企业”系统的前提大多以管理为中心。具体来说,将决策和配置交给容器,而不是依赖应用程序本身来管理这些资源。通过将资源的创建和管理与应用程序代码分离并依赖容器,系统管理员可以查看和访问这些资源,从而有可能在更高级别以通用方式调整和监控应用程序,而不是为此使用特定于应用程序的机制。

所以,这就是我们所处的环境,也是驱动 Java EE 规范中关于你能做什么和不能(不应该)做什么的“规则”的部分原因。

现在,servlet 容器规范更加狂野西部。它没有所有这些“企业”管理功能(请注意,许多容器公开了它们,但规范没有提及它们)。例如,提供静态文件是 Web 容器的基本功能,因此限制开发人员对所述文件的访问几乎没有意义。此外,servlet 规范出现在 EJB 规范之前,并且被固定在环境中,而不是根据该环境重做。

这为您提供了两个关于特定事物(如线程)的“矛盾”规范。

所以,是的,Servlet 规范“让你”管理自己的线程池,即使在 Java EE 应用程序中,即使这些线程池可能在完全相同的 JVM 中(因此“无法管理”消耗 Java EE 资源) Java EE 容器。

这在现实世界中的最终含义是,是的,如果您愿意,您可以在 Java EE 容器或 servlet 容器中假脱机线程等。没有一个流行的容器禁止您这样做(WebSphere 可能,我不使用它)。

但是,你不应该。Java EE(尤其是 Java EE 6)有机制和箍,你可以跳过来做事,而不是使用线程池。诸如 WorkManager、JMS 队列、异步会话 bean、计时器作业之类的东西。

在 servlet 应用程序中,这些机制中的大多数都不存在,因此您无法利用它们,因此您使用“just Java”来代替。

在使用 Java EE 应用程序部署的 Web 应用程序中使用“Just Java”的后果是容器内的可见性。例如,您的 Web 应用程序将需要自己的配置变量来设置其线程池的大小,并且不能依赖容器来管理它。

最后,这通常没什么大不了的。Java EE 的大部分复杂性都集中在许多人不使用的管理功能上。就我自己而言,我使用 Java EE 并且很少使用普通的 OL WAR,我喜欢尽可能多地向容器中推送 - 让它完成它的工作。也就是说,我在 Java EE 容器中的 WAR 中运行自定义套接字服务器,打破了所有可以想象的规则,仅仅是因为它更容易做到。“Java EE 方式”对于我们想要做的事情还不够灵活,所以我们选择了“Just Java”,并将代码投入到 WAR 中,这样我们就可以在狂野的西部玩耍,那里的男人就是男人,管理自己的线程。

于 2012-10-31T17:44:21.730 回答
2

EJB 是服务器管理的。管理意味着即依赖注入。如果您使用注释从类中生成线程,服务器将无法处理它们(执行@PostConstruct、注入引用等)。

于 2012-10-31T16:59:55.087 回答
0

EJB 始终在 EJB 容器中执行,因此不应在 EJB 中手动创建线程。即使它们是作为 WAR 文件(Web 模块)的包,它们也会在 EJB 容器中执行,并且在线程创建方面具有相同的限制。

但是,servlet 和过滤器是在 web 容器中执行的,没有什么可以阻止它们拥有自己的手动管理的线程池。

于 2012-10-31T17:19:15.363 回答