3、thrift原理重点分析之自动生成的代码详解
来源:互联网 发布:xampp for linux 编辑:程序博客网 时间:2024/05/17 15:02
我们用thrift-0.90.exe能够自动生成代码,仍用UserService.thrift为列
首先让我们先看一下自动生成的UserService类的结构
从这个类的结构中我们可以看到,主要有两个接口,两个Client,一个Processor,两个辅助的类*_agrs,*_result,*就是服务中的方法名称。
第一部分:接口部分:Iface、AsyncIface两个接口。
两个接口中的方法就是我们在thrift文件中定义的方法。例如:
在UserService.thrift中我们这样定义的:
service UserService {list<User> getUser() throws (1:Ex.thriftDataException dataEx,2:Ex.thriftBusinessException businessEx,3:Ex.thriftSystemException systemEx)}则在这两个接口中创建如下:
public interface Iface { public List<User> getUser() throws cn.stq.thrift.exception.thriftDataException, cn.stq.thrift.exception.thriftBusinessException, cn.stq.thrift.exception.thriftSystemException, org.apache.thrift.TException; } public interface AsyncIface { public void getUser(org.apache.thrift.async.AsyncMethodCallback<AsyncClient.getUser_call> resultHandler) throws org.apache.thrift.TException; }Iface这个接口用于同步调用,AsyncIface这个接口用于异步调用,并且AsyncIface接口方法中多了一个参数。
通常我们在实现服务的地方要实现这个接口。例如:
package cn.stq.thrift;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.thrift.TException;import cn.ruida.sms.portal.domain.User;import cn.stq.thrift.exception.thriftBusinessException;import cn.stq.thrift.exception.thriftDataException;import cn.stq.thrift.exception.thriftSystemException;public class UserServiceImpl implements UserService.Iface{public List<Map<String, String>> getUser() throws thriftDataException,thriftBusinessException, thriftSystemException, TException {List<Map<String, String>> list = new ArrayList<Map<String,String>>();Map<String,String>map = new HashMap<String, String>();map.put("loginName", "zhangsan");map.put("birthday", "2014-01-01");map.put("realName", "张三");list.add(map);return list;}private List<Map<String, String>> getUser(List<User> list,List<Map<String, String>> users) {for(User user:list){if(user==null){continue;}Map<String,String>map = new HashMap<String, String>();map.put("loginName", user.getLoginName());map.put("birthday", user.getBirthday());map.put("realName", user.getRealName());users.add(map);}return users;}}
并且在服务端创建TProcessor的是否也用到了这个接口:
TProcessor processor = new UserService.Processor<UserService.Iface>(new UserServiceImpl());
第二个部分:两个Client类 Client和AsyncClient,这两个Client分别对应上面的两个Iface接口,这两个Client分别实现了这两个接口。
Client类中有一下几个部分:Factory类,服务方法,send_*和recv_*方法
1)Factory类中提供了获取Client的方法。
public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> { public Factory() {} public Client getClient(org.apache.thrift.protocol.TProtocol prot) { return new Client(prot); } public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) { return new Client(iprot, oprot); } }第一个getClient方法只传入了一个TProtocol协议对象,第二个getClient方法传入了两个TProtocol协议对象,
iprot:表示输入协议对象,oprot:表示输出协议对象。
前者的方法只有一个协议对象,说明输入协议对象和输出协议对象是用的同一个对象。
2)服务方法。
这里所说的服务方法就是Iface接口中定义的方法,这个服务方法在每一个thrift文件生成的类中实现是相同的。
public List<User> getUser() throws cn.stq.thrift.exception.thriftDataException, cn.stq.thrift.exception.thriftBusinessException, cn.stq.thrift.exception.thriftSystemException, org.apache.thrift.TException { send_getUser(); return recv_getUser(); }这个服务方法首先调用send_*()方法,然后返回一个recv_*()方法。
3)send_*和revc_*方法
这里的*表示的是Iface接口的方法名称,不同的Iface,*是不同的。例如在UserService中方法名为getUser,则send_getUser()和recv_getUser().
send_*方法
public void send_getUser() throws org.apache.thrift.TException { getUser_args args = new getUser_args(); sendBase("getUser", args); }revc_*方法
public List<User> recv_getUser() throws cn.stq.thrift.exception.thriftDataException, cn.stq.thrift.exception.thriftBusinessException, cn.stq.thrift.exception.thriftSystemException, org.apache.thrift.TException { getUser_result result = new getUser_result(); receiveBase(result, "getUser"); if (result.isSetSuccess()) { return result.success; } if (result.dataEx != null) { throw result.dataEx; } if (result.businessEx != null) { throw result.businessEx; } if (result.systemEx != null) { throw result.systemEx; } throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUser failed: unknown result"); } }第三部分:Processor类
这个类的作用封装从输入输出流中读写数据的操作,它实现了TProcessor接口。这个类在整个通信的Processor层,即处理层,是协议层与用户实现的服务代码的纽带。
第四部分:两个辅助的类*_agrs,*_result
*_agrs类封装了服务方法中的参数,getUser()方法中没有参数,如果有参数的话,则参数就是*_agrs类的属性。并且在thrift文件定义的enum、struct、都在这个类中
public static class getUser_args implements org.apache.thrift.TBase<getUser_args, getUser_args._Fields>, java.io.Serializable, Cloneable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUser_args");*_result类封装了返回值和抛出的异常。如果有返回值的话,会存储在success属性中
public getUser_result getResult(I iface, getUser_args args) throws org.apache.thrift.TException { getUser_result result = new getUser_result(); try { result.success = iface.getUser(); } catch (cn.stq.thrift.exception.thriftDataException dataEx) { result.dataEx = dataEx; } catch (cn.stq.thrift.exception.thriftBusinessException businessEx) { result.businessEx = businessEx; } catch (cn.stq.thrift.exception.thriftSystemException systemEx) { result.systemEx = systemEx; } return result; } }通过上面的内容,我们对thrift文件自动生成的代码有了一个大致的了解。也就是我们对thrift的通信协议有了一定的了解,接下来我们就需要了解服务端和客户端是怎样的工作的了。
- 3、thrift原理重点分析之自动生成的代码详解
- 2、thrift的原理重点分析之协议规则thrift文件
- x264 代码重点详解 详细分析
- Thrift源码分析(三)-- IDL和生成代码分析
- Thrift 的TNonblockingServer运行原理分析
- Thrift 的TNonblockingServer运行原理分析
- MyBatisGenerator的自动生成代码之Eclipse
- MyBatisGenerator的自动生成代码之MyEclipse
- MyBatisGenerator的自动生成代码之MyEclipse
- MyBatisGenerator的自动生成代码之Eclipse
- thrift C++代码分析
- thrift自动生成源代码剖析
- Thrift之代码生成器Compiler原理及源码详细解析3
- Thrift之代码生成器Compiler原理及源码详细解析3
- Entity Framework自动生成的模型edmx文件代码分析
- ffmpeg mplayer x264 代码重点详解 详细分析
- thrift之compiler源码详解-3
- 编译原理之代码生成
- 信息学习15
- OpenGL之画一条线
- VBOX 共享文件夹
- img标签使用加载图片和错误时图片
- 展示vfork与fork区别的样例
- 3、thrift原理重点分析之自动生成的代码详解
- 时论-网络的自由与监控
- 如何判断链表中是否有环
- 传统线程互斥技术
- 如果缘识,是一树花开
- C# WCF 03 简单的IIS寄宿
- 我的爱百度搜不到
- lhnfw邻淹fOcEke
- 关于Python中的for循环控制语句