今天又繼續對Spring進行學習,其中一環便是利用Spring來解耦VS的WebService。先讓大家看看VS建立的WebService項目。
[WebService]
public class HelloWorldService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
WebService項目利用[WebService][WebMethod]等Attribute來描述Web服務和它所提供的方法。從某種角度來說,這樣做“污染”了原本幹淨的代碼。下面附上原來的代碼:
但是如果不用Attribute來描述WebService,我們應該如何去提供一個WebService,而且怎麼做才能不“污染”裡面的代碼呢?Spring為這個問題提供了一個很好的解決方案。正因為有Spring,一個平平無奇的HelloWorldService類,幾乎不用進行任何修改,就能夠利用其提供一個WebService。首先我們定義一個接口,來為ServerSide和ClientSide有一個共同的語言。再讓HelloWorldService實作這個接口。
interface IHelloWorld
string HelloWorld();
public class HelloWorldService:IHelloWorld
然後是做好ServerSide的Web.Config。
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="objects.xml"/>
</context>
</spring>
<httpHandlers>
<add verb="*" path="*.asmx" type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/>
</httpHandlers>
<httpModules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</httpModules>
配置好ServerSide的objects.xml,主要内容如下:
<object id="IHelloWorld" type="SpringService.HelloWorldService, SpringService"/>
<object id="HelloWorldService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="IHelloWorld"/>
<property name="Description" value="Test!Test!Test!" />
<property name="Namespace" value="http://myApp/webservices"/>
</object>
WebServiceExporter負責輸出WebService。隻要重新編譯一次項目,伺服器就會提供http://localhost:2955/HelloWorldService.asmx這樣的WebService。簡單吧?實際代碼中隻添加了一個接口,完全符合面向對象程式設計。下面介紹ClientSide如何通過接口調用HelloWorldService。
ClientSide對于Spring的配置App.Config更簡單,如下:
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="objects.xml"/>
</context>
</spring>
</configuration>
接着是ClientSide的object.xml,
<object id="HelloWorld" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
<property name="ServiceUri" value="http://localhost:2955/HelloWorldService.asmx"/>
<property name="ServiceInterface" value="Interfaces.IHelloWorld, Interfaces"/>
WebServiceProxyFactory恰如其名,負責産生WebService通路代理。下面隻要把HelloWorld注入到你想調用WebService的類中,就行了。最簡單的調用方法是:IHelloWorld ws = GetObject() As IHelloWorld 然後,ws.HelloWorld就可以了。
總結:Spring為Service建立WebService時清除了不幹淨的代碼,為ClientSide建立通路代理而不需要每添加一個WebService就添加一次Web引用。當兩者需要更換新的WebService時,隻需要修改配置檔案,就能夠達到相應的目的,而不需要改動代碼。Spring能夠把new的代碼完全從代碼中分離出來,降低了對象之間的耦合性。用了Spring後,由于代碼都是基于接口而編寫的,更利于做Mock測試(mock測試:就是在測試過程中,對于某些不容易構造或者 不容易擷取的對象,用一個虛拟的對象來建立以便測試的測試方法。mock對象:這個虛拟的對象就是mock對象。mock對象就是真實對象在調試期間的代替品。)