在java web应用程序中,我需要调用远程soap服务,并且我正在尝试使用CXF 2.5.0生成的客户端。 soap服务由特定的ERP供应商提供,其wsdl是可怕的,数千种类型,数十种xsd导入等。由于-autoNameResolution标志,wsdl2java生成客户端ok。但是在运行时它会检索远程wsdl两次,一次是在创建服务对象时,另一次是在创建端口对象时。
MyService_Service myService = new MyService_Service(giantWsdlUrl); // fetches giantWsdl
MyService myPort = myService.getMyServicePort(); // fetches giantWsdl again
为什么?我可以理解在创建myService时检索它,你想看到它与我正在使用的客户端匹配,或者让运行时wsdl位置指示端点地址等。但是我不明白为什么要求端口重新加载它只是的所有东西都在线上了。我错过了什么吗?
由于这是在一个Web应用程序中,而我can't be sure that myPort is threadsafe,所以我必须为每个线程创建一个端口,除非它太慢,6到8秒,这要归功于怪异的wsdl。或者添加我自己的池,提前创建一堆,并进行结账和签到。呸。
对于记录,JaxWsProxyFactoryBean creation route 不会获取wsdl,这对我的情况有好处。它仍然需要很长时间在第一个create()上,然后在后续的create()s上大约四分之一秒,甚至不太理想。而且我不知道...它有点像我在引擎盖下热线而不是转动钥匙。 :)
答案 0 :(得分:1)
嗯,你实际上已经自己回答了这个问题。每次调用service.getPort()
时,WSDL都会从远程站点加载并进行解析。 JaxWsProxyFactoryBean
完全相同,但是一旦获得代理,它就会被重新用于进一步的调用。这就是为什么第一轮运行缓慢(因为“预热”),但随后很快。
是的,JaxWsProxyFactoryBean
不是线程安全的。池化客户端代理是一种选择,但不幸的是会占用大量内存,如JAX-WS runtime model is not shared among client proxies;同步可能是更好的方法。