本文介绍 HSF 一些特性的使用方法及注意事项。
所有特性的实例 Demo 请在这里下载:Demo 下载
前提条件
使用 HSF 相关特性,请在 POM 文件中加入以下 edas-sdk 依赖。
- [backcolor=transparent]<dependency>
- [backcolor=transparent] [backcolor=transparent]<groupId>[backcolor=transparent]com.alibaba.edas[backcolor=transparent]</groupId>
- [backcolor=transparent] [backcolor=transparent]<artifactId>[backcolor=transparent]edas-sdk[backcolor=transparent]</artifactId>
- [backcolor=transparent] [backcolor=transparent]<version>[backcolor=transparent]1.5.1[backcolor=transparent]</version>
- [backcolor=transparent]</dependency>
隐式传参(目前仅支持字符串传输)
隐式传参一般用于传递一些简单 KV 数据,又不想通过接口方式传递,类似于 Cookie。
[backcolor=transparent]单个参数传递
服务消费者:
RpcContext.getContext().setAttachment("key", "args test");
服务提供者:
String keyVal=RpcContext.getContext().getAttachment("key");
[backcolor=transparent]多个参数传递
服务消费者:
-
[backcolor=transparent]
Map[backcolor=transparent]
<[backcolor=transparent]
String[backcolor=transparent]
,[backcolor=transparent]
String[backcolor=transparent]
>[backcolor=transparent]
map[backcolor=transparent]
=[backcolor=transparent]
new[backcolor=transparent]
[backcolor=transparent]
HashMap[backcolor=transparent]
<[backcolor=transparent]
String[backcolor=transparent]
,[backcolor=transparent]
String[backcolor=transparent]
>();
- [backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]put[backcolor=transparent]([backcolor=transparent]"param1"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"param1 test"[backcolor=transparent]);
- [backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]put[backcolor=transparent]([backcolor=transparent]"param2"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"param2 test"[backcolor=transparent]);
- [backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]put[backcolor=transparent]([backcolor=transparent]"param3"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"param3 test"[backcolor=transparent]);
- [backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]put[backcolor=transparent]([backcolor=transparent]"param4"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"param4 test"[backcolor=transparent]);
- [backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]put[backcolor=transparent]([backcolor=transparent]"param5"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"param5 test"[backcolor=transparent]);
- [backcolor=transparent]RpcContext[backcolor=transparent] rpcContext [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]RpcContext[backcolor=transparent].[backcolor=transparent]getContext[backcolor=transparent]();
- [backcolor=transparent]rpcContext[backcolor=transparent].[backcolor=transparent]setAttachments[backcolor=transparent]([backcolor=transparent]map[backcolor=transparent]);
服务提供者:
- [backcolor=transparent]Map[backcolor=transparent]<[backcolor=transparent]String[backcolor=transparent],[backcolor=transparent]String[backcolor=transparent]>[backcolor=transparent] map[backcolor=transparent]=[backcolor=transparent]rpcContext[backcolor=transparent].[backcolor=transparent]getAttachments[backcolor=transparent]();
- [backcolor=transparent]Set[backcolor=transparent]<[backcolor=transparent]String[backcolor=transparent]>[backcolor=transparent] [backcolor=transparent]set[backcolor=transparent]=[backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]keySet[backcolor=transparent]();
- [backcolor=transparent]for[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]String[backcolor=transparent] key [backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]set[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
- [backcolor=transparent] [backcolor=transparent]System[backcolor=transparent].[backcolor=transparent]out[backcolor=transparent].[backcolor=transparent]println[backcolor=transparent]([backcolor=transparent]"map value:"[backcolor=transparent]+[backcolor=transparent]map[backcolor=transparent].[backcolor=transparent]get[backcolor=transparent]([backcolor=transparent]key[backcolor=transparent]));
- [backcolor=transparent]}
异步调用
支持异步调用 callback 和 future 两种方式。
[backcolor=transparent]callback 调用方式
客户端配置为 callback 方式调用时,需要配置一个实现了 HSFResponseCallback 接口的 listener ,结果返回之后, HSF 会调用 HSFResponseCallback 中的方法。
[backcolor=transparent]注意:这个 HSFResponseCallback 接口的 listener 不能是内部类,否则 Pandora 的 classloader 在加载时就会报错。
XML 中的配置:
-
[backcolor=transparent]
<hsf:consumer[backcolor=transparent]
[backcolor=transparent]
id[backcolor=transparent]
=[backcolor=transparent]
"demoApi"[backcolor=transparent]
[backcolor=transparent]
interface[backcolor=transparent]
=[backcolor=transparent]
"com.alibaba.demo.api.DemoApi"
- [backcolor=transparent] [backcolor=transparent]version[backcolor=transparent]=[backcolor=transparent]"1.1.2"[backcolor=transparent] [backcolor=transparent]group[backcolor=transparent]=[backcolor=transparent]"test"[backcolor=transparent] [backcolor=transparent]>
- [backcolor=transparent] [backcolor=transparent]<hsf:asyncallMethods>
- [backcolor=transparent] [backcolor=transparent]<hsf:method[backcolor=transparent] [backcolor=transparent]name[backcolor=transparent]=[backcolor=transparent]"ayncTest"[backcolor=transparent] [backcolor=transparent]type[backcolor=transparent]=[backcolor=transparent]"callback"[backcolor=transparent]
- [backcolor=transparent] [backcolor=transparent]listener[backcolor=transparent]=[backcolor=transparent]"com.alibaba.ifree.hsf.consumer.AsynABTestCallbackHandler"[backcolor=transparent] [backcolor=transparent]/>
- [backcolor=transparent] [backcolor=transparent]</hsf:asyncallMethods>
- [backcolor=transparent] [backcolor=transparent]</hsf:consumer>
其中 AsynABTestCallbackHandler 类,是实现了 HSFResponseCallback 接口。DemoApi 接口中有一个方法是 ayncTest 。
代码示例
- [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]void[backcolor=transparent] onAppResponse[backcolor=transparent]([backcolor=transparent]Object[backcolor=transparent] appResponse[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
- [backcolor=transparent] [backcolor=transparent]//这里获取到异步调用后的值
- [backcolor=transparent] [backcolor=transparent]String[backcolor=transparent] msg [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]String[backcolor=transparent])[backcolor=transparent]appResponse[backcolor=transparent];
- [backcolor=transparent] [backcolor=transparent]System[backcolor=transparent].[backcolor=transparent]out[backcolor=transparent].[backcolor=transparent]println[backcolor=transparent]([backcolor=transparent]"msg:"[backcolor=transparent]+[backcolor=transparent]msg[backcolor=transparent]);
- [backcolor=transparent]}
[backcolor=transparent]注意:- 由于只用方法名字来标识方法,所以并不区分重载的方法。同名的方法都会被设置为同样的调用方式。
- 不支持在 call 里再发起 HSF 调用。这种做法可能导致 IO 线程挂起,无法恢复。
[backcolor=transparent]future 调用方式
客户端配置为 future 方式调用时,发起调用之后,通过 HSFResponseFuture 中的 public static Object getResponse(long timeout) 来获取返回结果。
XML 中的配置:
- [backcolor=transparent]<hsf:consumer[backcolor=transparent] [backcolor=transparent]id[backcolor=transparent]=[backcolor=transparent]"demoApi"[backcolor=transparent] [backcolor=transparent]interface[backcolor=transparent]=[backcolor=transparent]"com.alibaba.demo.api.DemoApi"[backcolor=transparent] [backcolor=transparent]version[backcolor=transparent]=[backcolor=transparent]"1.1.2"[backcolor=transparent] [backcolor=transparent]group[backcolor=transparent]=[backcolor=transparent]"test"[backcolor=transparent] [backcolor=transparent]>
- [backcolor=transparent] [backcolor=transparent]<hsf:asyncallMethods>
- [backcolor=transparent] [backcolor=transparent]<hsf:method[backcolor=transparent] [backcolor=transparent]name[backcolor=transparent]=[backcolor=transparent]"ayncTest"[backcolor=transparent] [backcolor=transparent]type[backcolor=transparent]=[backcolor=transparent]"future"[backcolor=transparent] [backcolor=transparent]/>
- [backcolor=transparent] [backcolor=transparent]</hsf:asyncallMethods>
- [backcolor=transparent]</hsf:consumer>
代码示例如下。
单个业务异步处理:
-
[backcolor=transparent]
//发起调用
- [backcolor=transparent]demoApi[backcolor=transparent].[backcolor=transparent]ayncTest[backcolor=transparent]();
- [backcolor=transparent]// 处理业务
- [backcolor=transparent]...
- [backcolor=transparent]//直接获得消息(若无需获得结果,可以不用操作该步骤)
- [backcolor=transparent]String[backcolor=transparent] msg[backcolor=transparent]=([backcolor=transparent]String[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]HSFResponseFuture[backcolor=transparent].[backcolor=transparent]getResponse[backcolor=transparent]([backcolor=transparent]3000[backcolor=transparent]);
多个业务需要并发处理:
若是多个业务需要并发处理,可以先获取 future,进行存储起来,等调用完毕后在使用。
-
[backcolor=transparent]
//定义集合
- [backcolor=transparent]List[backcolor=transparent]<[backcolor=transparent]HSFFuture[backcolor=transparent]>[backcolor=transparent] futures [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]ArrayList[backcolor=transparent]<[backcolor=transparent]HSFFuture[backcolor=transparent]>();
方法内进行并行调用:
-
[backcolor=transparent]
//发起调用
- [backcolor=transparent]demoApi[backcolor=transparent].[backcolor=transparent]ayncTest[backcolor=transparent]();
- [backcolor=transparent]//第一步获取future对象
- [backcolor=transparent]HSFFuture[backcolor=transparent] future[backcolor=transparent]=[backcolor=transparent]HSFResponseFuture[backcolor=transparent].[backcolor=transparent]getFuture[backcolor=transparent]();
- [backcolor=transparent]futures[backcolor=transparent].[backcolor=transparent]add[backcolor=transparent]([backcolor=transparent]future[backcolor=transparent]);
- [backcolor=transparent]//继续调用其他业务(同样采取异步调用)
- [backcolor=transparent]HSFFuture[backcolor=transparent] future[backcolor=transparent]=[backcolor=transparent]HSFResponseFuture[backcolor=transparent].[backcolor=transparent]getFuture[backcolor=transparent]();
- [backcolor=transparent]futures[backcolor=transparent].[backcolor=transparent]add[backcolor=transparent]([backcolor=transparent]future[backcolor=transparent]);
- [backcolor=transparent]// 处理业务
- [backcolor=transparent]...
- [backcolor=transparent]//获得数据并做处理
- [backcolor=transparent]for[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]HSFFuture[backcolor=transparent] hsfFuture [backcolor=transparent]:[backcolor=transparent] futures[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
- [backcolor=transparent] [backcolor=transparent]String[backcolor=transparent] msg[backcolor=transparent]=([backcolor=transparent]String[backcolor=transparent])[backcolor=transparent] hsfFuture[backcolor=transparent].[backcolor=transparent]getResponse[backcolor=transparent]([backcolor=transparent]3000[backcolor=transparent]);
- [backcolor=transparent] [backcolor=transparent]//处理相应数据
- [backcolor=transparent] [backcolor=transparent]...
- [backcolor=transparent]}
泛化调用
通过泛化调用可以组合接口、方法、参数进行RPC调用,无需依赖任何业务API。
[backcolor=transparent]
操作步骤
在消费者配置中加入泛化属性。
- [backcolor=transparent]<hsf:consumer[backcolor=transparent] [backcolor=transparent]id[backcolor=transparent]=[backcolor=transparent]"demoApi"[backcolor=transparent] [backcolor=transparent]interface[backcolor=transparent]=[backcolor=transparent]"com.alibaba.demo.api.DemoApi"[backcolor=transparent] [backcolor=transparent]group[backcolor=transparent]=[backcolor=transparent]"unittest"[backcolor=transparent] [backcolor=transparent]generic[backcolor=transparent]=[backcolor=transparent]"true"[backcolor=transparent]/>
[backcolor=transparent]
说明:generic 代表泛化参数,true 表示支持泛化,false 表示不支持,默认为 false。
DemoApi 接口方法:
- [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]String[backcolor=transparent] dealMsg[backcolor=transparent]([backcolor=transparent]String[backcolor=transparent] msg[backcolor=transparent]);
- [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]GenericTestDO[backcolor=transparent] dealGenericTestDO[backcolor=transparent]([backcolor=transparent]GenericTestDO[backcolor=transparent] testDO[backcolor=transparent]);
获取demoApi进行强制转换为泛化服务
导入泛化服务接口
-
[backcolor=transparent]
[backcolor=transparent]
import[backcolor=transparent]
com[backcolor=transparent]
.[backcolor=transparent]
alibaba[backcolor=transparent]
.[backcolor=transparent]
dubbo[backcolor=transparent]
.[backcolor=transparent]
rpc[backcolor=transparent]
.[backcolor=transparent]
service[backcolor=transparent]
.[backcolor=transparent]
GenericService
获取泛化对象
-
[backcolor=transparent]
[backcolor=transparent]
//若WEB项目中,可通过Spring bean进行注入后强转,这里是单元测试,所以采用加载配置文件方式
- [backcolor=transparent] [backcolor=transparent]ClassPathXmlApplicationContext[backcolor=transparent] consumerContext [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]ClassPathXmlApplicationContext[backcolor=transparent]([backcolor=transparent]"hsf-generic-consumer-beans.xml"[backcolor=transparent]);
- [backcolor=transparent] [backcolor=transparent]GenericService[backcolor=transparent] svc [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]GenericService[backcolor=transparent])[backcolor=transparent] consumerContext[backcolor=transparent].[backcolor=transparent]getBean[backcolor=transparent]([backcolor=transparent]"demoApi"[backcolor=transparent]);
泛化接口
- [backcolor=transparent] [backcolor=transparent]Object[backcolor=transparent] $invoke[backcolor=transparent]([backcolor=transparent]String[backcolor=transparent] methodName[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]String[backcolor=transparent][][backcolor=transparent] parameterTypes[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]Object[backcolor=transparent][][backcolor=transparent] args[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]throws[backcolor=transparent] [backcolor=transparent]GenericException[backcolor=transparent];
[backcolor=transparent]
说明:
methodName:需要调用的方法名称。
parameterTypes:需要调用方法参数的类型。
args:需要传输的参数值。
泛化调用(String类型参数)
- [backcolor=transparent]svc[backcolor=transparent].[backcolor=transparent]$invoke[backcolor=transparent]([backcolor=transparent]"dealMsg"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]String[backcolor=transparent][][backcolor=transparent] [backcolor=transparent]{[backcolor=transparent] [backcolor=transparent]"java.lang.String"[backcolor=transparent] [backcolor=transparent]},[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]Object[backcolor=transparent][][backcolor=transparent] [backcolor=transparent]{[backcolor=transparent] [backcolor=transparent]"hello"[backcolor=transparent] [backcolor=transparent]})
泛化调用(对象参数)
- [backcolor=transparent]// 第一步构造实体对象GenericTestDO,该实体有id、name两个属性
- [backcolor=transparent]GenericTestDO[backcolor=transparent] genericTestDO [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]GenericTestDO[backcolor=transparent]();
- [backcolor=transparent]genericTestDO[backcolor=transparent].[backcolor=transparent]setId[backcolor=transparent]([backcolor=transparent]1980l[backcolor=transparent]);
- [backcolor=transparent]genericTestDO[backcolor=transparent].[backcolor=transparent]setName[backcolor=transparent]([backcolor=transparent]"genericTestDO-tst"[backcolor=transparent]);
- [backcolor=transparent]// 使用 PojoUtils 生成二方包pojo的描述
- [backcolor=transparent]Object[backcolor=transparent] comp [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]PojoUtils[backcolor=transparent].[backcolor=transparent]generalize[backcolor=transparent]([backcolor=transparent]genericTestDO[backcolor=transparent]);
- [backcolor=transparent]// 服务泛化调用
- [backcolor=transparent]svc[backcolor=transparent].[backcolor=transparent]$invoke[backcolor=transparent]([backcolor=transparent]"dealGenericTestDO"[backcolor=transparent],[backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]String[backcolor=transparent][][backcolor=transparent] [backcolor=transparent]{[backcolor=transparent] [backcolor=transparent]"com.alibaba.demo.generic.domain.GenericTestDO"[backcolor=transparent] [backcolor=transparent]},[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]Object[backcolor=transparent][][backcolor=transparent] [backcolor=transparent]{[backcolor=transparent] comp [backcolor=transparent]});