我正在研究Jax-WS规范及其在Glassfish 3.1.2上的实现。我构建了一个简单的标准示例,其中通过使用通过wsimport生成的工件从jsp页面调用基于jax-ws soap的Web服务(webservice和jsp页面都部署在Glassfish中的同一个EAR中,但是在2个不同的战争中)
一切都按预期工作但我有一个问题:查看应用程序日志,似乎Glassfish每次调用时都会创建一个新的webservice实例。我想知道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服务实现的对象(此处称为实现者)以及一些配置信息......
通常会调用端点来为并发请求提供服务,因此应编写其实现者以支持多个线程。可以像往常一样使用synchronized关键字来控制对关键代码段的访问。为了更好地控制用于调度传入请求的线程,应用程序可以直接设置要使用的执行程序......“
即使在Jax-WS 2.2规范(Glassfish 3使用)中也存在此注释。
实际上,如果我仅使用JavaSE 7(包括Jax-WS 2.2)构建Web服务,则此描述是正确的,因为只有一个Web服务实例。 JavaEE是否有任何理由不遵守此政策?
非常感谢你的帮助,
尼科
答案 0 :(得分:0)
我在此规范(JSR-109)上找到了答案:
http://jcp.org/aboutJava/communityprocess/mrel/jsr109/index3.html
它描述了Jax-WS如何在JavaEE上运行:
“ 4.1客户端编程模型(第18页)
客户端必须假定Web服务的方法没有跨多个Web服务方法调用持久的状态。客户端可以将Web服务实现视为无状态。
客户端无法控制服务器上Web服务实现的生命周期。客户端不会创建或销毁Web服务的实例,这称为端口。客户端只访问端口。 Ports的生命周期或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.Endpoint(第43页)
JAX-WS提供了使用javax.xml.ws.Endpoint API动态创建和发布Web Service端点的功能。在托管环境中,此功能的使用被视为不可移植。要求Servlet和EJB容器都不允许动态发布端点,方法是不授予publishEndpoint安全权限。“