IDL是很多RPC框架用来支持跨语言环境调用的一个服务描述组件,一般都是采用文本格式来定义。 更多IDL的思考查看《理解WSDL, IDL》
Thrift的不同版本定义IDL的语法也不太相同,这里使用Thrift-0.8.0这个版本来介绍Java下的IDL定义
1. namespace 定义包名
2. struct 定义服务接口的参数,返回值使用到的类结构。如果接口的参数都是基本类型,则不需要定义struct
3. service 定义接口
一个简单的例子,IDL文件以.thrift为后缀名。
demo.thrift
1. 定义了生成的Java文件的包名为com.thrift.test
2. 定义了一个struct类结构作为参数
3.定义了一个service接口,返回值是int,方法名叫demoMethod,参数有三个,第一个是字符串类型,第二个是上面定义的类Parameter,第三个是Map类型
namespace java com.thrift.test
struct Parameter{
1: required i32 id;
2: required string name;
}
service DemoService{
i32 demoMethod(1:string param1, 2:Parameter param2, 3:map<string,string> param3);
}
IDL支持的数据类型包括以下部分
bool 布尔型
byte 8位整数
i16 16位整数
i32 32位整数
i64 64位整数
double 双精度浮点数
string 字符串
binary 字节数组
list<i16> List集合,必须指明泛型
map<string, string> Map类型,必须指明泛型
set<i32> Set集合,必须指明泛型
有了IDL之后,就可以使用thrift来自动生成辅助代码,包括客户端代码和序列化接口的代码
thrift -r --gen java demo.thrift
生成的代码如下
每个Struct会单独生成一个类,每个Service会生成一个类。
看一下生成类的具体结构
生成的类主要有5个部分
1. 接口类型,默认名称都是Iface。这个接口类型被服务器和客户端共同使用。服务器端使用它来做顶层接口,编写实现类。客户端代码使用它作为生成代理的服务接口。
自动生成的接口有两个,一个是同步调用的Iface,一个是异步调用的AsyncIface。异步调用的接口多了一个回调参数。
public interface Iface {
public int demoMethod(String param1, Parameter param2, Map<String,String> param3) throws org.apache.thrift.TException;
}
public interface AsyncIface {
public void demoMethod(String param1, Parameter param2, Map<String,String> param3, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.demoMethod_call> resultHandler) throws org.apache.thrift.TException;
}
2. 客户端类型,一个同步调用的客户端Client,一个异步调用的客户端AsyncClient
3. Processor,用来支持方法调用,每个服务的实现类都要使用Processor来注册,这样最后服务器端调用接口实现时能定位到具体的实现类。后面会有专门的文章介绍
4.方法参数的封装类,以"方法名_args"命名
5.方法返回值的封装类,以"方法名_result"命名
看一下生成的同步调用客户端Client的具体代码
1. 提供一个工厂方法来创建Client对象
2.接口方法的客户端代理,只做了两件事,发送方法调用请求;接收返回值
发送方法调用请求做了2件事
1. 创建方法参数对象,封装方法参数
2. 调用父类的sendBase方法来发送消息。发送消息时先通过writeMessageBegin发送消息头,再调用方法参数对象的write(TProtocol)方法发送消息体&#x