分類  >  Web前端 >

怎麼實現Spring管理上的不依賴於伺服器端啟動與否的WebService客戶端

tags:    時間:2013-12-10 21:21:05
如何實現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'>&lt;</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'>&gt;</span><span>      </span></span></li>
    <li class=''><span>   <span class='tag'>&lt;/</span><span class='tag-name'>simple:client</span><span class='tag'>&gt;</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的源代碼。

推薦閱讀文章

Bookmark the permalink ,來源:互聯網