[EDAS][HSF]開發 HSF 應用(EDAS SDK)

開發 HSF 應用(EDAS SDK)

更新時間:2019-04-19 12:01:13html

  • 本頁目錄
    • 快速開始
    • 開發高級特性
    • 單元測試

您可使用 EDAS-SDK 開發 HSF 應用,實現服務註冊發現,還能夠實現隱式傳參、異步調用、泛化調用、調用鏈路 Filter 擴展等高級 HSF 特性,以及 HSF 單元測試。java

快速開始

介紹如何使用 EDAS-SDK 快速開發 HSF 應用,完成服務註冊與發現。web

下載 Demo 工程

本章中介紹的代碼都可以經過官方 Demo 獲取。spring

  1. 下載 Demo 工程。
  2. 解壓下載的壓縮包,能夠看到carshop文件夾,裏面包含 itemcenter-api,itemcenter 和 detail 三個 Maven 工程文件夾。
  • itemcenter-api:提供接口定義
  • itemcenter:生產者服務
  • detail:消費者服務

說明:請使用 JDK 1.7 及以上版本。api

定義服務接口

HSF 服務基於接口實現,當接口定義好以後,生產者將使用該接口實現具體的服務,消費者也是基於此接口去訂閱服務。 在 Demo 的itemcenter-api工程中,定義了一個服務接口 com.alibaba.edas.carshop.itemcenter.ItemService,內容以下:併發

public interface ItemService {
    public Item getItemById(long id);
    public Item getItemByName(String name);
}

該服務接口將提供兩個方法:getItemById 與 getItemByName。app

開發生產者服務

生產者將實現服務接口以提供具體服務。同時,若是使用了 Spring 框架,還須要在 .xml 文件中配置服務屬性。框架

說明:Demo 工程中的 itemcenter 文件夾爲生產者服務的示例代碼。dom

實現服務接口

能夠參考ItemServiceImpl.java文件中的示例:異步

package com.alibaba.edas.carshop.itemcenter;
public class ItemServiceImpl implements ItemService {
    @Override
    public Item getItemById( long id ) {
        Item car = new Item();
        car.setItemId( 1l );
        car.setItemName( "Mercedes Benz" );
        return car;
    }
    @Override
    public Item getItemByName( String name ) {
        Item car = new Item();
        car.setItemId( 1l );
        car.setItemName( "Mercedes Benz" );
        return car;
    }
}

配置服務屬性

上述示例主要實現了 com.alibaba.edas.carshop.itemcenter.ItemService,並在兩個方法中返回了一個 Item 對象。 代碼開發完成以後,除了在 web.xml 中進行必要的常規配置,您還須要增長相應的 Maven 依賴, 同時在 Spring 配置文件使用 <hsf /> 標籤註冊併發布該服務。具體內容以下: 在pom.xml中添加以下 Maven 依賴:

<dependencies>
     <!-- 添加 servlet 的依賴 -->
     <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>servlet-api</artifactId>
         <version>2.5</version>
         <scope>provided</scope>
     </dependency>
     <!-- 添加 Spring 的依賴 -->
     <dependency>
         <groupId>com.alibaba.edas.carshop</groupId>
         <artifactId>itemcenter-api</artifactId>
         <version>1.0.0-SNAPSHOT</version>
     </dependency>
     <!-- 添加服務接口的依賴 -->
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-web</artifactId>
         <version>2.5.6(及其以上版本)</version>
     </dependency>
     <!-- 添加 edas-sdk 的依賴 -->
     <dependency>
         <groupId>com.alibaba.edas</groupId>
        <artifactId>edas-sdk</artifactId>
         <version>1.5.0</version>
     </dependency>
</dependencies>

在 hsf-provider-beans.xml 文件中增長 Spring 關於 HSF 服務的配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:hsf="http://www.taobao.com/hsf"
     xmlns="http://www.springframework.org/schema/beans"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.taobao.com/hsf
     http://www.taobao.com/hsf/hsf.xsd" default-autowire="byName">
     <!-- 定義該服務的具體實現 -->
     <bean id="itemService" class="com.alibaba.edas.carshop.itemcenter.ItemServiceImpl" />
     <!-- 用 hsf:provider 標籤代表提供一個服務生產者 -->
     <hsf:provider id=「itemServiceProvider"
         <!-- 用 interface 屬性說明該服務爲此類的一個實現 -->
         interface=「com.alibaba.edas.carshop.itemcenter.ItemService"
         <!-- 此服務具體實現的 Spring 對象 -->
         ref=「itemService"
         <!-- 發佈該服務的版本號,可任意指定,默認爲 1.0.0 -->
         version=「1.0.0"
     </hsf:provider>
</beans>

上面的示例爲基本配置,您也能夠根據您的實際需求,參考下面的生產者服務屬性列表,增長其它配置。

生產者服務屬性列表

屬性 描述
interface 必須配置,類型爲 [String],爲服務對外提供的接口。
version 可選配置,類型爲 [String],含義爲服務的版本,默認爲 1.0.0。
clientTimeout 該配置對接口中的全部方法生效,可是若是客戶端經過 methodSpecials 屬性對某方法配置了超時時間,則該方法的超時時間以客戶端配置爲準。其餘方法不受影響,仍是以服務端配置爲準。
serializeType 可選配置,類型爲 [String(hessian|java)],含義爲序列化類型,默認爲 hessian。
corePoolSize 單獨針對這個服務設置核心線程池,從公用線程池中劃分出來。
maxPoolSize 單獨針對這個服務設置線程池,從公用線程池中劃分出來。
enableTXC 開啓分佈式事務 GTS。
ref 必須配置,類型爲 [ref],爲須要發佈爲 HSF 服務的 Spring Bean ID。
methodSpecials 可選配置,用於爲方法單獨配置超時時間(單位 ms),這樣接口中的方法能夠採用不一樣的超時時間。該配置優先級高於上面的 clientTimeout 的超時配置,低於客戶端的 methodSpecials 配置。

服務建立及發佈限制

名稱 示例 限制大小 是否可調整
{服務名}:{版本號} com.alibaba.edas.testcase.api.TestCase:1.0.0 最大192字節
組名 aliware 最大32字節
一個Pandora應用實例發佈的服務數 N/A 最大800個 可在應用基本信息頁面單擊應用設置部分右側的設置,在下拉列表中選擇JVM,在彈出的應用設置對話框中進入自定義->自定義參數,在輸入框中添加 -DCC.pubCountMax=1200 屬性參數(該參數值可根據應用實際發佈的服務數調整)。

生產者服務屬性配置示例

<bean id="impl" class="com.taobao.edas.service.impl.SimpleServiceImpl" />
    <hsf:provider id="simpleService" interface="com.taobao.edas.service.SimpleService"
        ref="impl" version="1.0.1" clientTimeout="3000" enableTXC="true"
        serializeType="hessian">
        <hsf:methodSpecials>
            <hsf:methodSpecial name="sum" timeout="2000" />
        </hsf:methodSpecials>
    </hsf:provider>

開發消費者服務

消費者訂閱服務從代碼編寫的角度分爲兩個部分。

  1. Spring 的配置文件使用標籤hsf:consumer/定義好一個 Bean。
  2. 在使用的時候從 Spring 的 context 中將 Bean 取出來。

說明:Demo 工程中的 detail 文件夾爲消費者服務的示例代碼。

配置服務屬性

與生產者同樣,消費者的服務屬性配置分爲 Maven 依賴配置與 Spring 的配置。

  1. pom.xml文件中添加 Maven 依賴。 Maven 依賴配置與生產者相同,詳情請參見開發生產者服務的配置服務屬性。
  2. hsf-consumer-beans.xml 文件中添加 Spring 關於 HSF 服務的配置。 增長消費者的定義,HSF 框架將根據該配置文件去服務中心訂閱所需的服務。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:hsf="http://www.taobao.com/hsf"
     xmlns="http://www.springframework.org/schema/beans"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.taobao.com/hsf
     http://www.taobao.com/hsf/hsf.xsd" default-autowire="byName">
     <!-- 消費一個服務示例 -->
     <hsf:consumer
         <!-- Bean ID,在代碼中可根據此 ID 進行注入從而獲取 consumer 對象  -->
         id="item"
         <!-- 服務名,與服務提供者的相應配置對應,HSF 將根據 interface + version 查詢並訂閱所需服務  -->
         interface="com.alibaba.edas.carshop.itemcenter.ItemService"
         <!-- 版本號,與服務提供者的相應配置對應,HSF 將根據 interface + version 查詢並訂閱所需服務  -->
         version="1.0.0"
     </hsf:consumer>
</beans>

配置服務調用

能夠參考StartListener.java文件中的示例:

public class StartListener implements ServletContextListener{
    @Override
    public void contextInitialized( ServletContextEvent sce ) {
        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext( sce.getServletContext() );
        // 根據 Spring 配置中的 Bean ID 「item」 獲取訂閱到的服務
        final ItemService itemService = ( ItemService ) ctx.getBean( "item" );
        ……
        // 調用服務 ItemService 的 getItemById 方法
        System.out.println( itemService.getItemById( 1111 ) );
        // 調用服務 ItemService 的 getItemByName 方法
        System.out.println( itemService.getItemByName( "myname is le" ) );
        ……
    }
}

上面的示例中爲基本配置,您也能夠根據您的實際需求,參考下面的服務屬性列表,增長其它配置。

消費者服務屬性列表

屬性 描述
interface 必須配置,類型爲 [String],爲須要調用的服務的接口。
version 可選配置,類型爲 [String],爲須要調用的服務的版本,默認爲1.0.0。
methodSpecials 可選配置,爲方法單獨配置超時時間(單位 ms)。這樣接口中的方法能夠採用不一樣的超時時間,該配置優先級高於服務端的超時配置。
target 主要用於單元測試環境和開發環境中,手動地指定服務提供端的地址。若是不想經過此方式,而是經過配置中心推送的目標服務地址信息來指定服務端地址,能夠在消費者端指定 -Dhsf.run.mode=0。
connectionNum 可選配置,爲支持設置鏈接到 server 鏈接數,默認爲1。在小數據傳輸,要求低延遲的狀況下設置多一些,會提高 TPS。
clientTimeout 客戶端統一設置接口中全部方法的超時時間(單位 ms)。超時時間設置優先級由高到低是:客戶端 methodSpecials,客戶端接口級別,服務端 methodSpecials,服務端接口級別 。
asyncallMethods 可選配置,類型爲 [List],設置調用此服務時須要採用異步調用的方法名列表以及異步調用的方式。默認爲空集合,即全部方法都採用同步調用。
maxWaitTimeForCsAddress 配置該參數,目的是當服務進行訂閱時,會在該參數指定時間內,阻塞線程等待地址推送,避免調用該服務時由於地址爲空而出現地址找不到的狀況。若超過該參數指定時間,地址仍是沒有推送,線程將再也不等待,繼續初始化後續內容。
注意,在應用初始化時,須要調用某個服務時才使用該參數。若是不須要調用其它服務,請勿使用該參數,會延長啓動啓動時間。
消費者服務屬性配置示例
<hsf:consumer id="service" interface="com.taobao.edas.service.SimpleService"
      version="1.1.0" clientTimeout="3000"
      target="10.1.6.57:12200?_TIMEOUT=1000" maxWaitTimeForCsAddress="5000">
      <hsf:methodSpecials>
           <hsf:methodSpecial name="sum" timeout="2000" ></hsf:methodSpecial>
      </hsf:methodSpecials>
</hsf:consumer>

發佈服務

完成代碼、接口開發和服務配置後,在 Eclipse 或 IDEA 中,可直接以 Ali-Tomcat 運行該服務 (具體請參照文檔開發工具準備中的配置 Eclipse 開發環境和配置 IDEA 開發環境)。

在開發環境配置時,有一些額外 JVM 啓動參數來改變 HSF 的行爲,具體以下: 屬性 描述 -Dhsf.server.port 指定 HSF 的啓動服務綁定端口,默認值爲 12200。 -Dhsf.serializer 指定 HSF 的序列化方式,默認值爲 hessian。 -Dhsf.server.max.poolsize 指定 HSF 的服務端最大線程池大小,默認值爲 600。 -Dhsf.server.min.poolsize 指定 HSF 的服務端最小線程池大小。默認值爲 50。 -DHSF_SERVER_PUB_HOST 指定對外暴露的 IP,若是不配置,使用 -Dhsf.server.ip 的值。 -DHSF_SERVER_PUB_PORT 指定對外暴露的端口,該端口必須在本機被監聽,並對外開放了訪問受權,默認使用 -Dhsf.server.port 的配置,若是 -Dhsf.server.port 沒有配置,默認使用12200。

開發環境查詢 HSF 服務

在開發調試的過程當中,若是您的服務是經過輕量配置中心進行服務註冊與發現,就能夠經過 EDAS 控制檯查詢某個應用提供或調用的服務。

假設您在一臺 IP 爲 192.168.1.100 的機器上啓動了 EDAS 配置中心。

  1. 進入 http://192.168.1.100:8080/
  2. 在左側菜單欄單擊服務列表,輸入服務名、服務組名或者 IP 地址進行搜索,查看對應的服務提供者以及服務調用者。

說明:配置中心啓動以後默認選擇第一塊網卡地址作爲服務發現的地址,若是開發者所在的機器有多塊網卡的狀況,可設置啓動腳本中的 SERVER_IP 變量進行顯式的地址綁定。

常見查詢案例

  • 提供者列表頁
    • 在搜索條件裏輸入 IP 地址,單擊搜索便可查詢該 IP 地址的機器提供了哪些服務。
    • 在搜索條件裏輸入服務名或服務分組,便可查詢哪些 IP 地址提供了這個服務。
  • 調用者列表頁
    • 在搜索條件裏輸入 IP 地址,單擊搜索便可查詢該 IP 地址的機器調用了哪些服務。
    • 在搜索條件裏輸入服務名或服務分組,便可查詢哪些 IP 地址調用了這個服務。

開發高級特性

在您參照上面的快速開始開發完基本的應用以後,下面將向您介紹如何在上面的應用中實現隱式傳參、異步調用、泛化調用和 Filter 鏈路擴展等 HSF 的高級特性。您能夠直接下載 Demo。 隱式傳參(目前僅支持字符串傳輸)

隱式傳參通常用於傳遞一些簡單 KV 數據,又不想經過接口方式傳遞,相似於 Cookie。 單個參數傳遞 服務消費者: RpcContext.getContext().setAttachment("key", "args test"); 服務提供者: String keyVal=RpcContext.getContext().getAttachment("key"); 多個參數傳遞

服務消費者:

Map<String,String> map=new HashMap<String,String>();
map.put("param1", "param1 test");
map.put("param2", "param2 test");
map.put("param3", "param3 test");
map.put("param4", "param4 test");
map.put("param5", "param5 test");
RpcContext rpcContext = RpcContext.getContext();
rpcContext.setAttachments(map);

服務提供者:

Map<String,String> map=rpcContext.getAttachments();
Set<String> set=map.keySet();
for (String key : set) {
  System.out.println("map value:"+map.get(key));
}

說明:隱式傳參只對單次調用有效,當消費端調用返回後,會自動擦除 RpcContext 中的信息。

異步調用

支持 callback 和 future 兩種異步調用方式。 callback 調用方式 客戶端配置爲 callback 方式時,須要配置一個實現了 HSFResponseCallback 接口的 listener。結果返回以後, HSF 會調用 HSFResponseCallback 中的方法。 注意:這個 HSFResponseCallback 接口的 listener 不能是內部類,不然 Pandora 的 classloader 在加載時就會報錯。 XML 中的配置:

<hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi"
      version="1.1.2" >
      <hsf:asyncallMethods>
          <hsf:method name="ayncTest" type="callback" 
           listener="com.alibaba.ifree.hsf.consumer.AsynABTestCallbackHandler" />
      </hsf:asyncallMethods>
</hsf:consumer>

其中 AsynABTestCallbackHandler 類實現了 HSFResponseCallback 接口。DemoApi 接口中有一個方法是 ayncTest 。 代碼示例

public void onAppResponse(Object appResponse) {
  //獲取到異步調用後的值
 String msg = (String)appResponse;
 System.out.println("msg:"+msg);
}

注意: 因爲只用方法名字來標識方法,因此並不區分重載的方法。同名的方法都會被設置爲一樣的調用方式。 不支持在 call 裏再發起 HSF 調用。這種作法可能致使 IO 線程掛起,沒法恢復。 future 調用方式 客戶端配置爲 future 方式時,發起調用以後,經過 HSFResponseFuture 中的 public static Object getResponse(long timeout) 來獲取返回結果。 XML 中的配置:

<hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi" version="1.1.2" >
  <hsf:asyncallMethods>
         <hsf:method name="ayncTest" type="future"  />
  </hsf:asyncallMethods>
</hsf:consumer>

代碼示例以下。 單個調用異步處理:

//發起調用
demoApi.ayncTest();
// 處理業務
...
//直接得到消息(若無需得到結果,能夠不用操做該步驟)
String msg=(String) HSFResponseFuture.getResponse(3000);

多個調用須要併發處理: 如果多個業務須要併發處理,能夠先獲取 future,存儲起來,等調用完畢後再使用。

//定義集合
List<HSFFuture> futures = new ArrayList<HSFFuture>();
方法內進行並行調用:
試用
//發起調用
demoApi.ayncTest();
//第一步獲取 future 對象
HSFFuture future=HSFResponseFuture.getFuture();
futures.add(future);
//繼續調用其餘業務(一樣採起異步調用)
HSFFuture future=HSFResponseFuture.getFuture();
futures.add(future);
// 處理業務
...
//得到數據並作處理
for (HSFFuture hsfFuture : futures) {
   String msg=(String) hsfFuture.getResponse(3000);
   //處理相應數據
   ...
}

泛化調用

經過泛化調用能夠組合接口、方法、參數進行 RPC 調用,無需依賴任何業務 API。 步驟一:在消費者 XML 配置中加入泛化屬性

<hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi" generic="true"/>

說明:generic 表明泛化參數,true 表示支持泛化,false 表示不支持,默認爲 false。

DemoApi 接口方法:

public String dealMsg(String msg);
public GenericTestDO dealGenericTestDO(GenericTestDO testDO);

步驟二:獲取 demoApi 進行強制轉換爲泛化服務

導入泛化服務接口

import com.alibaba.dubbo.rpc.service.GenericService

獲取泛化對象 XML 加載方式

//若 WEB 項目中,可經過 Spring bean 進行注入後強制轉換,這裏是單元測試,因此採用加載配置文件方式
  ClassPathXmlApplicationContext consumerContext = new ClassPathXmlApplicationContext("hsf-generic-consumer-beans.xml");
  //強制轉換接口爲 GenericService
  GenericService svc = (GenericService) consumerContext.getBean("demoApi");

代碼訂閱方式

HSFApiConsumerBean consumerBean = new HSFApiConsumerBean();  
consumerBean.setInterfaceName("com.alibaba.demo.api.DemoApi");
consumerBean.setGeneric("true"); // 設置 generic 爲 true
consumerBean.setVersion("1.0.0");
consumerBean.init();
// 強制轉換接口爲 GenericService
GenericService svc = (GenericService) consumerBean.getObject();

步驟三:泛化接口

Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException;

接口參數說明: methodName:須要調用的方法名稱。 parameterTypes:須要調用方法參數的類型。 args:須要傳輸的參數值。

步驟四:泛化調用

String 類型參數

svc.$invoke("dealMsg", new String[] { "java.lang.String" }, new Object[] { "hello" })

對象參數,服務端和客戶端須要保證相同的對象

// 第一步構造實體對象 GenericTestDO,該實體有 id、name 兩個屬性
  GenericTestDO genericTestDO = new GenericTestDO();
  genericTestDO.setId(1980l);
  genericTestDO.setName("genericTestDO-tst");
  // 使用 PojoUtils 生成二方包 pojo 的描述
  Object comp = PojoUtils.generalize(genericTestDO);
  // 服務泛化調用
  svc.$invoke("dealGenericTestDO",new String[] { "com.alibaba.demo.generic.domain.GenericTestDO" }, new Object[] { comp });

調用鏈路 Filter 擴展

下載 Demo。

基礎接口

public interface ServerFilter extends RPCFilter {
}
public interface ClientFilter extends RPCFilter {
}
public interface RPCFilter {
    ListenableFuture<RPCResult> invoke(InvocationHandler invocationHandler, Invocation invocation) throws Throwable;
    void onResponse(Invocation invocation, RPCResult rpcResult);
}

實現步驟

實現 ServerFilter 進行服務端攔截。 實現 ClientFilter 進行客戶端攔截。 業務經過標準的 META-INF/services/com.taobao.hsf.invocation.filter.RPCFilter 文件來註冊 Filter。 實現示例

import com.taobao.hsf.invocation.Invocation;
import com.taobao.hsf.invocation.InvocationHandler;
import com.taobao.hsf.invocation.RPCResult;
import com.taobao.hsf.invocation.filter.ServerFilter;
import com.taobao.hsf.util.PojoUtils;
import com.taobao.hsf.util.concurrent.ListenableFuture;
public class HSFServerFilter implements ServerFilter {
    public ListenableFuture<RPCResult> invoke(InvocationHandler invocationHandler, Invocation invocation) throws Throwable {
        //process args
        String[]  sigs = invocation.getMethodArgSigs();
        Object [] args = invocation.getMethodArgs();
        System.out.println("#### intercept request");
        for(String sig : sigs) {
            System.out.print(sig);
            System.out.print(";");
        }
        System.out.println();
        for(Object arg : args) {
            System.out.println(PojoUtils.generalize(arg));
            System.out.print(";");
        }
        System.out.println();
        return invocationHandler.invoke(invocation);
    }
    public void onResponse(Invocation invocation, RPCResult rpcResult) {
        System.out.println("#### intercept response");
        Object resp = rpcResult.getHsfResponse().getAppResponse();
        System.out.println(PojoUtils.generalize(resp));
    }
}

配置 META-INF/services/com.taobao.hsf.invocation.filter.RPCFilter

com.alibaba.edas.carshop.itemcenter.filter.HSFServerFilter

運行效果

intercept request

long 1111 intercept response

試用 {itemId=1, itemName=Mercedes Benz, class=com.alibaba.edas.carshop.itemcenter.Item} 可選的 Filter

在一些場景下,您定製了 filter,可是隻但願在某些服務上使用,這時可使用可選的 Filter。具體作法是在對應的 Filter上 增長 @Optional 註解,以下: 試用

@Optional
@Name("HSFOptionalServerFilter")
public class HSFOptionalServerFilter implements ServerFilter {
    public ListenableFuture<RPCResult> invoke(InvocationHandler invocationHandler,
                                              Invocation invocation) throws Throwable {
        System.out.println("#### HSFOptionalServerFilter intercept request");
        return invocationHandler.invoke(invocation);
    }
    public void onResponse(Invocation invocation, RPCResult rpcResult) {
        System.out.println("#### HSFOptionalServerFilter intercept response");
    }
}

當指定服務須要使用該 Filter 時,只須要在配置的 Bean 上聲明便可,配置以下:

<bean class="com.taobao.hsf.app.spring.util.HSFSpringProviderBean">
    <property name="serviceInterface" value="com.alibaba.middleware.hsf.guide.api.service.OrderService" />
    <property name="version" value="1.0.0" />
    <property name="group" value="HSF" />
    <property name="includeFilters">
        <list>
            <value>HSFOptionalServerFilter</value>
            <value>NoFilter</value>
        </list>
    </property>
    <property name="target" ref="orderService" />
</bean>

上述配置的服務,將會使用全部的非 @Optional 修飾的 ServerFilter ,而且會包括 HSFOptionalServerFilter 和 NoFilter,而 HSFOptionalServerFilter 的名稱是來自於對應的 Filter 配置上的 @Name 修飾。

若是沒法找到該名稱的 Filter ,只會提醒您,可是不會致使您沒法啓動或者運行。

單元測試

在測試環境中,有兩種方式作單元測試。 方式一 經過 LightApi 代碼發佈和訂閱服務 方式二 經過 XML 配置發佈訂閱服務 相關樣例請下載 Demo。 方式一 經過 LightApi 代碼發佈和訂閱服務

在 Maven 中添加 LightApi 依賴。

<dependency>
     <groupId>com.alibaba.hsf</groupId>
     <artifactId>LightApi</artifactId>
     <version>1.0.5</version>
 </dependency>

注意: 請使用 1.0.5 或以上版本的 LightApi,不然可能遇到 hsf: can not load class {com.taobao.hsf.address.AddressService} after all phase的錯誤。 建立 ServiceFactory。 這裏須要設置 Pandora 的地址,參數是 SAR 包所在目錄。若是 SAR 包地址是 /Users/Jason/Work/AliSoft/PandoraSar/DevSar/taobao-hsf.sar,則參數以下:

private static final ServiceFactory factory = ServiceFactory.getInstanceWithPath("/Users/Jason/Work/AliSoft/PandoraSar/DevSar");

經過代碼進行發佈和訂閱服務。

// 進行服務發佈(如有發佈者,無需再在這裏寫)
 factory.provider("helloProvider")// 參數是一個標識,初始化後,下次只需調用 provider("helloProvider")便可提供對應服務
         .service("com.alibaba.edas.unit.service.UnitTestService")// 接口全類名
         .version("1.0.0")// 版本號
         .impl(new UnitTestServiceImpl())// 對應的服務實現
         .publish();// 發佈服務,至少要調用 service()和 version()才能夠發佈服務
 // 進行服務消費
 factory.consumer("helloConsumer")// 參數是一個標識,初始化後,下次只需調用 consumer("helloConsumer")便可直接提供對應服務
         .service("com.alibaba.edas.unit.service.UnitTestService")// 接口全類名
         .version("1.0.0")// 版本號
         .subscribe();
 factory.consumer("helloConsumer").sync();// 同步等待地址推送,最多6秒。
 UnitTestService log4jService = (UnitTestService) factory.consumer("helloConsumer").subscribe();// 用 ID 獲取對應服務,subscribe()方法返回對應的接口
 // 調用服務方法
 System.out.println("bean -> msg rec success:-"+log4jService.print());

方式二 經過 XML 配置發佈訂閱服務

編寫好 HSF 的 XML 配置。 經過代碼方式加載配置文件。

//XML 方式加載服務提供者
new ClassPathXmlApplicationContext("hsf-provider-beans.xml");
//XML 方式加載服務消費者
ClassPathXmlApplicationContext consumerContext=new ClassPathXmlApplicationContext("hsf-consumer-beans.xml");
//獲取 Bean
UnitTestXMLConsumer unitTestXMLConsumer=(UnitTestXMLConsumer) consumerContext.getBean("unitTestConsumer");
//服務調用 
unitTestXMLConsumer.testUnitProvider();

參考

阿里雲官網 - 幫助文檔: 企業級分佈式應用服務 EDAS > 應用開發 > 使用 HSF 開發應用 > 使用 Ali-Tomcat 開發應用 > 開發 HSF 應用(EDAS SDK)

相關文章
相關標籤/搜索