Glassfish 3 上的 Jax-WS 2.2 Web 服务实例管理



我正在研究Jax-WS规范及其在Glassfish 3.1.2上的实现。我构建了一个简单的标准示例,其中使用通过 wsimport 生成的工件从 jsp 页面调用基于 jax-ws soap 的 Web 服务(Web 服务和 jsp 页面都部署在同一个 EAR 中的 Glassfish 上,但在 2 场不同的战争中)。

一切都按预期工作,但我有一个问题:查看应用程序日志,似乎 Glassfish 每次调用时都会创建一个新的 Web 服务实例。我想知道 Java 在哪里正式定义了 Web 容器应该如何管理 Web 服务实例,以及开发人员是否可以自定义此行为。

我在这里阅读了jax-ws 2.1规范

http://download.oracle.com/otndocs/jcp/jaxws-2.1-mrel2-eval-oth-JSpec/

但是在谈到如何使用 Endpoint 类手动发布 Web 服务时,我只发现了一个线索(第 5.2.2 节"发布",第 69 页):

"端点由一个充当 Web 服务实现的对象(此处称为实现器)加上一些配置信息组成......

通常会调用终结点来处理并发请求,因此应编写其实现器以支持多个线程。sync 关键字可以像往常一样用于控制对代码关键部分的访问。为了更好地控制用于调度传入请求的线程,应用程序可以直接设置要使用的执行器..."

这个注释甚至存在于 Jax-WS 2.2 规范(由 Glassfish 3 使用)中。

实际上,如果我只使用 JavaSE 7(包括 Jax-WS 2.2)构建一个 Web 服务,这个描述是正确的,因为只有一个 Web 服务实例。JavaEE不遵循此政策有什么原因吗?

非常感谢您的帮助,

尼科

我在这个规范(JSR-109)上找到了答案:

http://jcp.org/aboutJava/communityprocess/mrel/jsr109/index3.html

它描述了 Jax-WS 在 JavaEE 上的工作原理:

"4.1 客户端编程模型(第18页)

客户端必须假定 Web 服务的方法没有在多个 Web 服务方法调用中持久的状态。客户端可以将 Web 服务实现视为无状态。

客户端无法控制服务器上 Web 服务实现的生命周期。客户端不会创建或销毁 Web 服务(称为端口)的实例。客户端仅访问端口。端口或 Web 服务实现实例的生命周期由承载 Web 服务的运行时管理。端口没有标识。这意味着客户端无法将端口与其他端口进行比较以查看它们是否相同或相同,客户端也无法访问特定的端口实例。

5.3.2.4.2 JAX-WS 的 Web 容器编程模型(第 42 页)

服务实现必须是无状态对象。服务实现 Bean 不得在 Bean 实例的数据成员内或实例外部跨方法调用保存客户机特定的状态。容器可以使用任何 Bean 实例来为请求提供服务。

5.3.4 服务实现 Bean 生命周期(第 43 页)

在为请求提供服务之前,容器必须实例化服务实现 Bean 并为方法请求做好准备。容器可以池化服务实现 Bean 的方法就绪实例,并在处于方法就绪状态的任何实例上调度方法请求。

此外,规范指出JavaEE不得使用Endpoint类来发布Web服务:

"5.3.3 发布端点 – javax.xml.ws.端点(第 43 页)

JAX-WS 提供了使用 javax.xml.ws.Endpoint API 动态创建和发布 Web 服务端点的功能。此功能的使用在托管环境中被视为不可移植。要求 Servlet 和 EJB 容器都不允许动态发布端点,因为不授予 publishEndpoint 安全权限。

最新更新