阅读851 返回首页    go 微信


HSF 特性使用__服务开发_开发者指南_企业级分布式应用服务 EDAS-阿里云

本文介绍 HSF 一些特性的使用方法及注意事项。

所有特性的实例 Demo 请在这里下载:Demo 下载

前提条件

使用 HSF 相关特性,请在 POM 文件中加入以下 edas-sdk 依赖。

  1. <dependency>
  2. <groupId>com.alibaba.edas</groupId>
  3. <artifactId>edas-sdk</artifactId>
  4. <version>1.5.1</version>
  5. </dependency>

隐式传参(目前仅支持字符串传输)

隐式传参一般用于传递一些简单 KV 数据,又不想通过接口方式传递,类似于 Cookie。

  • 单个参数传递

    服务消费者:

    RpcContext.getContext().setAttachment("key", "args test");

    服务提供者:

    String keyVal=RpcContext.getContext().getAttachment("key");

  • 多个参数传递

    服务消费者:

    1. Map<String,String> map=new HashMap<String,String>();
    2. map.put("param1", "param1 test");
    3. map.put("param2", "param2 test");
    4. map.put("param3", "param3 test");
    5. map.put("param4", "param4 test");
    6. map.put("param5", "param5 test");
    7. RpcContext rpcContext = RpcContext.getContext();
    8. rpcContext.setAttachments(map);

    服务提供者:

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

异步调用

支持异步调用 callback 和 future 两种方式。

  • callback 调用方式

    客户端配置为 callback 方式调用时,需要配置一个实现了 HSFResponseCallback 接口的 listener ,结果返回之后, HSF 会调用 HSFResponseCallback 中的方法。

    注意:这个 HSFResponseCallback 接口的 listener 不能是内部类,否则 Pandora 的 classloader 在加载时就会报错。

    XML 中的配置:

    1. <hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi"
    2. version="1.1.2" group="test" >
    3. <hsf:asyncallMethods>
    4. <hsf:method name="ayncTest" type="callback"
    5. listener="com.alibaba.ifree.hsf.consumer.AsynABTestCallbackHandler" />
    6. </hsf:asyncallMethods>
    7. </hsf:consumer>

    其中 AsynABTestCallbackHandler 类,是实现了 HSFResponseCallback 接口。DemoApi 接口中有一个方法是 ayncTest 。

    代码示例

    1. public void onAppResponse(Object appResponse) {
    2. //这里获取到异步调用后的值
    3. String msg = (String)appResponse;
    4. System.out.println("msg:"+msg);
    5. }

    注意:

    • 由于只用方法名字来标识方法,所以并不区分重载的方法。同名的方法都会被设置为同样的调用方式。
    • 不支持在 call 里再发起 HSF 调用。这种做法可能导致 IO 线程挂起,无法恢复。
  • future 调用方式

    客户端配置为 future 方式调用时,发起调用之后,通过 HSFResponseFuture 中的 public static Object getResponse(long timeout) 来获取返回结果。

    XML 中的配置:

    1. <hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi" version="1.1.2" group="test" >
    2. <hsf:asyncallMethods>
    3. <hsf:method name="ayncTest" type="future" />
    4. </hsf:asyncallMethods>
    5. </hsf:consumer>

    代码示例如下。

    • 单个业务异步处理:

      1. //发起调用
      2. demoApi.ayncTest();
      3. // 处理业务
      4. ...
      5. //直接获得消息(若无需获得结果,可以不用操作该步骤)
      6. String msg=(String) HSFResponseFuture.getResponse(3000);
    • 多个业务需要并发处理:

      若是多个业务需要并发处理,可以先获取 future,进行存储起来,等调用完毕后在使用。

      1. //定义集合
      2. List<HSFFuture> futures = new ArrayList<HSFFuture>();
    • 方法内进行并行调用:

      1. //发起调用
      2. demoApi.ayncTest();
      3. //第一步获取future对象
      4. HSFFuture future=HSFResponseFuture.getFuture();
      5. futures.add(future);
      6. //继续调用其他业务(同样采取异步调用)
      7. HSFFuture future=HSFResponseFuture.getFuture();
      8. futures.add(future);
      9. // 处理业务
      10. ...
      11. //获得数据并做处理
      12. for (HSFFuture hsfFuture : futures) {
      13. String msg=(String) hsfFuture.getResponse(3000);
      14. //处理相应数据
      15. ...
      16. }

泛化调用

通过泛化调用可以组合接口、方法、参数进行RPC调用,无需依赖任何业务API。

操作步骤

在消费者配置中加入泛化属性。
  1. <hsf:consumer id="demoApi" interface="com.alibaba.demo.api.DemoApi" group="unittest" generic="true"/>

说明:generic代表泛化参数,true标识支持泛化,false标识不支持,默认为false。

DemoApi接口方法:

  1. public String dealMsg(String msg);
  2. public GenericTestDO dealGenericTestDO(GenericTestDO testDO);
获取demoApi进行强制转换为泛化服务
  • 导入泛化服务接口

    1. import com.alibaba.dubbo.rpc.service.GenericService
  • 获取泛化对象

    1. //若WEB项目中,可通过Spring bean进行注入后强转,这里是单元测试,所以采用加载配置文件方式
    2. ClassPathXmlApplicationContext consumerContext = new ClassPathXmlApplicationContext("hsf-generic-consumer-beans.xml");
    3. GenericService svc = (GenericService) consumerContext.getBean("demoApi");
泛化接口
  1. Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException;

说明:

methodName:需要调用的方法名称。

parameterTypes:需要调用方法参数的类型。

args:需要传输的参数值。

泛化调用(String类型参数)
  1. svc.$invoke("dealMsg", new String[] { "java.lang.String" }, new Object[] { "hello" })
泛化调用(对象参数)
  1. // 第一步构造实体对象GenericTestDO,该实体有id、name两个属性
  2. GenericTestDO genericTestDO = new GenericTestDO();
  3. genericTestDO.setId(1980l);
  4. genericTestDO.setName("genericTestDO-tst");
  5. // 使用 PojoUtils 生成二方包pojo的描述
  6. Object comp = PojoUtils.generalize(genericTestDO);
  7. // 服务泛化调用
  8. svc.$invoke("dealGenericTestDO",new String[] { "com.alibaba.demo.generic.domain.GenericTestDO" }, new Object[] { comp });

最后更新:2016-11-23 16:04:20

  上一篇:go 消费者订阅服务__服务开发_开发者指南_企业级分布式应用服务 EDAS-阿里云
  下一篇:go HSF 单元测试__服务开发_开发者指南_企业级分布式应用服务 EDAS-阿里云