这就是 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 中,这样我们就可以在狂野的西部玩耍,那里的男人就是男人,管理自己的线程。