您的问题的最短答案当然是让 EJB 能够像 Servlet 一样工作是一个好主意,在 EJB 3.1 中,我们添加了一个可以完全做到这一点的组件:@Singleton
一个@Singleton
bean 可以像 servlet 一样是多线程的,通过以下任一方式:
- 使用
@ConcurrencyManagement(BEAN)
- 与需要并发的方法和非线程安全的方法
@ConcurrencyManagement(CONTAINER)
一起使用。@Lock(READ)
@Lock(WRITE)
Servlet 多年来一直拥有而 EJB 从未拥有的另一件事是,<load-on-startup>
它允许 Servlet 急切地加载并在应用程序启动时工作。
为了匹配 Servlet <load-on-start>
,我们添加了@Startup
可以添加到任何@Singleton
EJB 的注解,并将导致它在应用程序启动时启动。这些 bean 将@PostConstruct
在应用程序启动时调用它们的方法,并@PreDestroy
在应用程序关闭时调用它们。
与其使用数字 ( ) 来指示使用start 注释的 bean<load-on-startup>1</load-on-startup>
的顺序,不如使用并指定需要在带注释的 bean 之前启动的 bean 的列表。@Startup
@DependsOn
我们在 EJB 3.1 中为对齐 Servlet 和 EJB 所做的一个鲜为人知和理解的方面当然是允许将 EJB 打包到.war
文件中——这不是鲜为人知的部分——当我们这样做时,我们悄悄地改变了定义ofjava:comp/env
以匹配 Servlet 方法。
在 EJB 3.1 之前,不可能有两个 EJB 共享一个java:comp/env
名称空间(java:comp/env
在 EJB 规范中是 bean 范围的)。相比之下,Servlet 从来没有任何方式让单个 Servlet 拥有自己的私有java:comp/env
命名空间(java:comp/env
在 Servlet 规范中是模块范围的)。因此,在 EJB 3.1 中,打包在 war 中的 EJB 将具有与 webapp 中的所有其他 Servlet 和 EJB 相同的模块范围命名空间,这与打包在 EAR 中时 EJB 获得java:comp/env
的 bean 范围命名空间形成了很大的对比java:comp/env
一场战争之外。我们就那个争论了好几个星期。
不错的一点啤酒时间琐事,可以用来测验你的朋友。