基于Netty高性能RPC框架Nifty协议、传输层、编解码( 三 )


ThriftCatalog:
private final ConcurrentMap typeCache = new ConcurrentHashMap<>();public ThriftType getThriftType(Type javaType) throws IllegalArgumentException{ThriftType thriftType = typeCache.get(javaType);if (thriftType == null) {thriftType = getThriftTypeUncached(javaType);typeCache.putIfAbsent(javaType, thriftType);}return thriftType;}复制代码基于此 , 在构建ThriftMethodProcessor的时候 , 再跟进ThriftCodecManager就能得到Map>
ImmutableMap.Builder> builder = ImmutableMap.builder();for (ThriftFieldMetadata fieldMetadata : methodMetadata.getParameters()) {builder.put(fieldMetadata.getId(), codecManager.getCodec(fieldMetadata.getThriftType()));}parameterCodecs = builder.build();复制代码所以在处理接收到的数据的时候 , 可以根据fieldid来获取对应的编解码器了 。
知道ThriftType如何获得后 , 再回过头来看ReflectionThriftStructCodec如何解析结构体的 。
protected final ThriftStructMetadata metadata;protected final SortedMap> fields;@Overridepublic T read(TProtocol protocol) throws Exception {TProtocolReader reader = new TProtocolReader(protocol);Map data = http://kandian.youth.cn/index/new HashMap<>(metadata.getFields().size());while (reader.nextField()) {short fieldId = reader.getFieldId();ThriftCodec codec = fields.get(fieldId);Object value = http://kandian.youth.cn/index/reader.readField(codec);data.put(fieldId, value);}// build the structreturn constructStruct(data);}复制代码代码简化了很多 , 但是主体逻辑留了下来 。 从这部分代码可以看到 , 这和服务端读取数据的逻辑是一样的 , 具体的可以参考服务端读取数据 。 最后得到的data中key为 struct(即java对象)的fieldId , value则为属性的值 。 比如传入的对象class Dog{int age = 5; String name = "tom"}那么两个data中的数据为{1=5 , 2="tom"} , 最后在constructStruct构建对象 。
编解码器在前面其实介绍过编解码器ThrfitCodec , 为了符合标题 , 这里再啰嗦一遍 。
Thrift提供的编解码器顶层接口为ThriftCodec , 提供了read和write方法
public interface ThriftCodec{/*** The Thrift type this codec supports.The Thrift type contains the Java generic Type of the* codec.*/public ThriftType getType();/*** Reads a value from supplied Thrift protocol reader.** @param protocol the protocol to read from* @return the value; not null* @throws Exception if any problems occurred when reading or coercingthe value*/public T read(TProtocol protocol) throws Exception;/*** Writes a value to the supplied Thrift protocol writer.** @param value the value to write; not null* @param protocol the protocol to write to* @throws Exception if any problems occurred when writing or coercingthe value*/public void write(T value, TProtocol protocol) throws Exception;}复制代码同时Thrift也为我们提供了常用的编解码器 , 足以应付我们业务的使用 。 比如常见的基本类型的编解码器 , String类型编解码器 StringThriftCodec:
public class StringThriftCodec implements ThriftCodec {@Overridepublic ThriftType getType() {return ThriftType.STRING;}@Overridepublic String read(TProtocol protocol) throws Exception {return protocol.readString();}@Overridepublic void write(String value, TProtocol protocol) throws Exception{protocol.writeString(value);}}复制代码


推荐阅读