2012-07-01 31 views
4

有一个excellent article by Young Yang,它解释了如何使用wsimport来创建具有异步Web服务调用的Web服务客户端构件。异步要求WSDL在其绑定部分标签使用JAX-WS进行异步Web服务调用:使用wsimport支持异步或自动启动?

<enableAsyncMapping>true</enableAsyncMapping>

。如果您使用自下而上的方法处理JAX-WS注释的Java类,则无法直接在WSDL中执行此操作,因为WSDL是Web服务器上生成的工件。相反,当您在WSDL上执行wsimport时,您可以使用构建工具(如Ant或Maven)来包含此绑定。

所生成的客户端构件具有异步方法调用返回一个

Future<?> 

Response 

这是一个未来。

在阅读Yang的文章后,我的问题是,为什么不仅仅使用Executors和Futures来滚动我自己的异步Web服务调用。 wsimport创建的工件是否提供了一些我无法用自己的方法看到的优势?

如果任何人有这两种方法的经验或见解,我将不胜感激您的反馈。

+0

谢谢你的链接 – ACV

回答

6

理论上,生成的异步客户端不需要阻塞线程。通过传递AsyncHandler,系统可以在Web服务调用完成时使用NIO注册事件,并且可以调用该处理程序。根本没有线程需要阻塞。

如果您将同步 Web服务调用插入执行程序,它仍然会阻塞线程直到结果到达,但至少该阻塞仅限于执行程序中的线程池。

只要有数百个线程在浮动,您的系统性能就会因上下文切换而降低。

引擎盖下的Web服务库是否实际使用NIO是另一回事。它看起来并不是JAX-WS规范所要求的。使用JDK 1.6并设置断点服务器端,我设置了100个客户端来调用服务器。使用JVisualVM我连接到客户端,可以看到它每次调用服务器时都创建了一个新线程。垃圾!

环顾网络,我发现Apache CXF支持限制异步调用中使用的线程池。果然,使用由CXF生成的客户端并将正确的库放在类路径中,如here所述,重新测试表明只有25个线程正在使用。

那么为什么要使用jax-ws API而不是自己构建?由于构建自己需要更多的工作;-)

1

我知道,它没有达到促使问题,但只是补充列入问题一个信息:

“而是使用样订做Ant或Maven工具,包括在WSDL上执行wsimport时执行此绑定。“

有可能通过使用选项-b到的wsimport一个添加自定义XML文件生成对异步客户端:

实施例:

wsimport -p helloAsyncClient -keep http://localhost:8080/helloservice?wsdl -b customAsync.xml 

的customAsync.xml内容:

<jaxws:bindings 
     wsdlLocation="http://localhost:8080/helloservice?wsdl" 
     xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"> 
     <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping> 
</jaxws:bindings> 

这只是另一种通过使用ant或maven生成异步客户端的方法:)