如何实现Spring管理下的不依赖于服务器端启动与否的WebService客户端??????? 最近在项目中遇到一种情况,就
如何实现Spring管理下的不依赖于服务器端启动与否的WebService客户端
??????? 最近在项目中遇到一种情况,就是两个程序需要使用WebService互通数据,有时系统A需要调用系统B提供的WebService服务,有时系统B需要调用系统A提供的WebService服务。
??????? 我使用Spring 管理下的 Apache CXF 来实现WebService服务。现在遇到的问题是,Spring管理的WebService客户端使用org.apache.cxf.frontend.ClientProxyFactoryBean 的一个bean来实现,这个东西需要在配置文件中写死WebService服务器端的地址,当系统启动的时候,Spring就会尝试去访问这个地址,来初始化这个bean。这也就意味着客户端必须依赖与服务器端启动与否。
??????? 在我遇到的场景下,也就是系统A要使用系统B提供的WebService服务,系统A必须等待系统B启动以后才能启动;系统B需要使用系统A提供的WebService服务,系统B必须等待系统A启动以后才能启动。这是一个死循环。
??????? 那么,有没有什么办法,可以让WebService的客户端启动的时候,不必等待WebService的服务器端启动起来。而是在客户端真正去调用服务器端提供的服务的时候,才去尝试连接服务器?
??????? 如果使用代码来实现客户端,似乎是有办法的。但是我想利用Spring提供的WebService支持以简化开发,在Spring管理下的客户端实现有没有什么办法解决这个问题?
??????? 我相信很多朋友都遇到过类似的问题。我也真正研究中。等有结果了再写上来。
1 楼 jnn 2007-10-10 CXF客户端在创建的时候需要获取WSDL来构建Service Model,而不是真正的要访问服务。所以要把你A,B两个服务的依赖循环解除,可以通过指定一个外部WSDL的方法来实现。<br/>
<br/>
<div class='code_title'>xml 代码</div>
<div class='dp-highlighter'>
<div class='bar'>?</div>
<ol class='dp-xml' start='1'>
<li class='alt'><span><span class='tag'><</span><span class='tag-name'>simple:client</span><span>?</span><span class='attribute'>id</span><span>=</span><span class='attribute-value'>"client2"</span><span>???</span></span></li>
<li class=''><span>????<span class='attribute'>serviceClass</span><span>=</span><span class='attribute-value'>"org.apache.cxf.service.factory.HelloService"</span><span>??</span></span></li>
<li class='alt'><span>????<span class='attribute'>wsdlLocation</span><span>?=?</span><span class='attribute-value'>"file://somewhere"</span><span>??</span></span></li>
<li class=''><span>????<span class='attribute'>serviceName</span><span>=</span><span class='attribute-value'>"s:XMLService"</span><span>??</span></span></li>
<li class='alt'><span>????<span class='attribute'>xmlns:s</span><span>=</span><span class='attribute-value'>"http://apache.org/hello_world_soap_http"</span><span>??</span></span></li>
<li class=''><span>????<span class='attribute'>endpointName</span><span>=</span><span class='attribute-value'>"s:XMLPort"</span><span>??????</span></span></li>
<li class='alt'><span>????<span class='attribute'>bindingId</span><span>=</span><span class='attribute-value'>"http://cxf.apache.org/bindings/xformat"</span><span class='tag'>></span><span>??????</span></span></li>
<li class=''><span>???<span class='tag'></</span><span class='tag-name'>simple:client</span><span class='tag'>></span><span>??</span></span></li>
</ol>
</div> 2 楼 fenixshadow 2008-01-01 很好,很强大。 3 楼 fenixshadow 2008-01-01 不过我觉得这样做太麻烦了,不如直接设定ClientProxyFactoryBean以及所有引用ClientProxyFactoryBean 的客户端bean都设定lazy-init="true",然后在getBean的时候注意捕获异常。感觉这样做比较符合常理,客户端只有在使用到的时候才初始化,因为不能保证服务端总是可用的。 4 楼 Frederick 2008-01-23 引用
不过我觉得这样做太麻烦了,不如直接设定ClientProxyFactoryBean以及所有引用ClientProxyFactoryBean 的客户端bean都设定lazy-init="true",然后在getBean的时候注意捕获异常。感觉这样做比较符合常理,客户端只有在使用到的时候才初始化,因为不能保证服务端总是可用的。
这个正是我现在使用的方式,似乎也是目前最好的方式了。
5 楼 daquan198163 2008-01-23 服务端中途断掉又连上呢?应该没有影响的吧,http无状态
有人试过么? 6 楼 Frederick 2008-01-30 引用
服务端中途断掉又连上呢?应该没有影响的吧,http无状态
我的经验是如果初始化的时候失败了,就必须重启服务器了。如果是初始化成功后,中间掉线,倒是没有问题。
问题是无法保证初始化的时候,服务器端是一定存在的。如果第一次需要访问WebService的时候,恰巧服务器端还没有启动起来,那么就挂了。幸好的是这种情况并不多见。 7 楼 ununreal 2008-01-30 如果是使用CFX的前身XFire时,使用的FactoryBean是org.codehaus.xfire.spring.remoting.XFireClientFactoryBean,用以下配置:
<property name="lookupServiceOnStartup">
<value>false</value>
</property>
达到启动Client端时不去访问对应的web service的服务端,我想这个属性在CFX中还有,具体lz可以看一下org.apache.cxf.frontend.ClientProxyFactoryBean的源代码。