3

将 Web 服务公开为无状态会话 bean 是否有任何与线程安全相关的好处?
(如果我错了,请纠正我)但我认为 Web 服务不是线程安全的,并且像 Servlet 一样,只有一个 Web 服务类的实例是由服务器创建的(不是每个请求一个实例)。

我不知道它们是否是从无状态 bean 的 bean 池中分配的 - 由应用程序服务器分配。我正在尝试查找是否将 @Stateless 注释与已使用 @WebService 注释注释的 Web 服务一起使用,这将强制应用服务器开始为每个传入请求从池中分配它们。这样我就确定我将为每个传入请求创建一个单独的实例?

4

1 回答 1

9

介绍

Web 服务端点使用的实例数取决于您使用的框架。

如果您使用简单的端点(即带有 Apache CXF 或 Spring webservices 的 JAX-WS),您将拥有一个用于所有线程/请求的服务实例(如您所说,Servlets)。因此,根据定义,这种服务是无状态的。但是如果你需要为服务添加一些状态,你可以这样做,但要由开发人员来确保服务线程安全。

当您使用 EJB 时,您拥有更大的灵活性:如果您使用无状态 bean,您将拥有一个实例池来管理所有请求(如果您的 poolSize=1,您将获得与 Apache CXF 相同的行为)。同样,您可以向无状态 bean 添加一些状态,但使其线程安全更加困难,因为您需要管理一个实例池。但是如果你需要一个状态,你可以使用一个有状态的 bean 来拥有一个框架,让你在线程安全方面的工作更轻松。

关于服务状态的一些提示

如果您不在服务中保留状态,则您的 Web 服务是线程安全的。换句话说,如果定义为线程安全,则无状态服务。

如果您需要一些应该由所有线程/请求共享的状态,您可以向无状态服务(JAX-WS 或具有 poolSize=1 的无状态会话 bean)添加一些状态,但您需要使其线程安全,添加 sycn 块(请不要同步您的@WebMethod)。重要提示:理论上(和实践中),您永远不应该向无状态会话 bean 添加状态,因为池可以在“想要”时销毁/创建实例。

如果您需要保留仅由当前线程/请求使用的状态,您可以使用ThreadLocal变量将一些状态添加到无状态服务,或者更轻松地使用有状态会话 bean。

现在终于回答你的问题了

  1. 当且仅当您使它们成为线程安全时,无状态会话 bean 才是线程安全的:它们不应该有状态 :-)
  2. 经典 Web 服务和无状态会话 bean Web 服务之间的唯一区别是第一个将具有单个实例,而第二个将使用实例池。如果您的 poolSize=1 您会得到相同的效果,但理论上,池可以在“想要”时破坏您的实例。

希望有帮助,

于 2012-07-15T18:05:24.593 回答