源码分析Dubbo序列化-源码分析kryo序列化实现原理

it2023-07-11  69

参考文档: https://blog.csdn.net/prestigeding/article/details/81748418

参考文档: https://www.jianshu.com/p/f56c9360936d

kryo是一个高性能的序列化/反序列化工具,由于其变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小的体积。

   Kryo的核心设计理念就是尽最大可能减少序列化后的文件大小,其举措1就是通过对long,int等数据类型,采用变长字节存储来代替java中使用固定字节(4,8)字节的模式,因为在软件开发中,对象的这些值基本上都是小值,能节省很多空间,第二个举措是使用了类似缓存的机制,在一次序列化对象中,在整个递归序列化期间,相同的对象,只会序列化一次,后续的用一个局部int值来代替。

以下简单分析下在dubbo中序列化的使用

 

 

 

protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) throws IOException { Serialization serialization = getSerialization(channel); // header. byte[] header = new byte[HEADER_LENGTH]; // set magic number. Bytes.short2bytes(MAGIC, header); // set request and serialization flag. header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId()); if (req.isTwoWay()) header[2] |= FLAG_TWOWAY; if (req.isEvent()) header[2] |= FLAG_EVENT; // set request id. Bytes.long2bytes(req.getId(), header, 4); // encode request data. int savedWriteIndex = buffer.writerIndex(); buffer.writerIndex(savedWriteIndex + HEADER_LENGTH); ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer); ObjectOutput out = serialization.serialize(channel.getUrl(), bos); if (req.isEvent()) { encodeEventData(channel, out, req.getData()); } else { encodeRequestData(channel, out, req.getData()); } out.flushBuffer(); if (out instanceof Cleanable) { ((Cleanable) out).cleanup(); } bos.flush(); bos.close(); int len = bos.writtenBytes(); checkPayload(channel, len); Bytes.int2bytes(len, header, 12); // write buffer.writerIndex(savedWriteIndex); buffer.writeBytes(header); // write header. buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len); }

 

public Kryo (ClassResolver classResolver, ReferenceResolver referenceResolver, StreamFactory streamFactory) { if (classResolver == null) throw new IllegalArgumentException("classResolver cannot be null."); this.classResolver = classResolver; classResolver.setKryo(this); this.streamFactory = streamFactory; streamFactory.setKryo(this); this.referenceResolver = referenceResolver; if (referenceResolver != null) { referenceResolver.setKryo(this); references = true; } addDefaultSerializer(byte[].class, ByteArraySerializer.class); addDefaultSerializer(char[].class, CharArraySerializer.class); addDefaultSerializer(short[].class, ShortArraySerializer.class); addDefaultSerializer(int[].class, IntArraySerializer.class); addDefaultSerializer(long[].class, LongArraySerializer.class); addDefaultSerializer(float[].class, FloatArraySerializer.class); addDefaultSerializer(double[].class, DoubleArraySerializer.class); addDefaultSerializer(boolean[].class, BooleanArraySerializer.class); addDefaultSerializer(String[].class, StringArraySerializer.class); addDefaultSerializer(Object[].class, ObjectArraySerializer.class); addDefaultSerializer(KryoSerializable.class, KryoSerializableSerializer.class); addDefaultSerializer(BigInteger.class, BigIntegerSerializer.class); addDefaultSerializer(BigDecimal.class, BigDecimalSerializer.class); addDefaultSerializer(Class.class, ClassSerializer.class); addDefaultSerializer(Date.class, DateSerializer.class); addDefaultSerializer(Enum.class, EnumSerializer.class); addDefaultSerializer(EnumSet.class, EnumSetSerializer.class); addDefaultSerializer(Currency.class, CurrencySerializer.class); addDefaultSerializer(StringBuffer.class, StringBufferSerializer.class); addDefaultSerializer(StringBuilder.class, StringBuilderSerializer.class); addDefaultSerializer(Collections.EMPTY_LIST.getClass(), CollectionsEmptyListSerializer.class); addDefaultSerializer(Collections.EMPTY_MAP.getClass(), CollectionsEmptyMapSerializer.class); addDefaultSerializer(Collections.EMPTY_SET.getClass(), CollectionsEmptySetSerializer.class); addDefaultSerializer(Collections.singletonList(null).getClass(), CollectionsSingletonListSerializer.class); addDefaultSerializer(Collections.singletonMap(null, null).getClass(), CollectionsSingletonMapSerializer.class); addDefaultSerializer(Collections.singleton(null).getClass(), CollectionsSingletonSetSerializer.class); addDefaultSerializer(TreeSet.class, TreeSetSerializer.class); addDefaultSerializer(Collection.class, CollectionSerializer.class); addDefaultSerializer(TreeMap.class, TreeMapSerializer.class); addDefaultSerializer(Map.class, MapSerializer.class); addDefaultSerializer(TimeZone.class, TimeZoneSerializer.class); addDefaultSerializer(Calendar.class, CalendarSerializer.class); addDefaultSerializer(Locale.class, LocaleSerializer.class); addDefaultSerializer(Charset.class, CharsetSerializer.class); addDefaultSerializer(URL.class, URLSerializer.class); OptionalSerializers.addDefaultSerializers(this); TimeSerializers.addDefaultSerializers(this); lowPriorityDefaultSerializerCount = defaultSerializers.size(); // Primitives and string. Primitive wrappers automatically use the same registration as primitives. register(int.class, new IntSerializer()); register(String.class, new StringSerializer()); register(float.class, new FloatSerializer()); register(boolean.class, new BooleanSerializer()); register(byte.class, new ByteSerializer()); register(char.class, new CharSerializer()); register(short.class, new ShortSerializer()); register(long.class, new LongSerializer()); register(double.class, new DoubleSerializer()); register(void.class, new VoidSerializer()); }

 

 

1. ChannelBuffer buffer; 2. Serialization serialization = getSerialization(channel); 3. ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer); 4. ObjectOutput out = serialization.serialize(channel.getUrl(), bos); 5. out.writeObject(data);

 

 

最新回复(0)