ActiveJ学习心得——serializer(1)

2021SC@SDUSC

一、Serializer概述

我在前面六个博客介绍了ActiveJ中的inject模块,关于每一个包中的每一个类我都进行了分析。接下来的博客就是对Serializer模块的介绍。
ActiveJ Serializer是世界上最快的Java串行器。 同时,它的功能非常强大,完全支持Java子类、集合(包括Maps),以及像HPPC这样的专门集合。 ActiveJ Serializer是ActiveJ技术之一,但它对第三方的依赖性很小,可以作为一个独立的组件使用。
ActiveJ Serializer特点:

  • 通过注解直接与Java类一起工作。 没有额外的中间DTO类层。
  • 使用运行时字节码生成来实现,与动态创建的类兼容。
  • 稳定的二进制格式,具有向后的二进制兼容性。
  • 支持计划的演变:可改变的版本,增加或删除的字段,等等。
  • 可以轻松扩展–你可以为特定的类编写自己的插件。
  • 包括特殊的提示,使代码更加有效。字符串格式,nullable,varlen,等等。
  • 为JVM的内在因素提供小恩典格式。
  • 支持不安全模式以获得最佳性能。
  • 任何复杂的循环引用。
  • UTF-8、UTF-16和ISO8859-1编码。
  • 甚至与复杂的集合、泛型和可忽略的值兼容。
    ActiveJ Serializer是非常方便和强大的
    ActiveJ Serializer是一个突破性的字节码生成器, 快速和空间效率的序列化程序。 它是令人难以置信的 ,功能强大的 ,即使是对复杂的对象也能利用 ,简单而直观的DSL工作。使用方法如以下代码所示:
public static class Person {
    
    
    public Person(@Deserialize("age") int age,
                  @Deserialize("name") String name) {
    
    
        this.age = age;
        this.name = name;
    }

    @Serialize(order = 0)
    public int age;

    @Serialize(order = 1)
    public final String name;
}

二、core-serializer结构

源代码中core-serializer结构如下:

如上图所示,core-serializer的核心代码部分是io.activej.serializer这个包。这个包下面有annotations,impl,stream,util这四个包和AbstractSerializerDef、BinaryInput、BinaryOutput、BinarySerializer、BinarySerializers、CompatibilityLevel、CorruptedDataException、SerializerBuilder、SerializerDef、StringFormat这10个单独的类。这一次的博客就是读一下其中几个重要的单独的类的功能。

三、代码解读

1.SerializerDef类
SerializerDef类是一个interface接口,表示特定类到字节数组的序列化程序和反序列化程序,这是对serializer的定义。这个接口中定义了一些尚未实现的方法和接口,下面就来看一下。
以下代码是返回将被序列化的对象的原始类型,再下面的Map类型的参数是编码和解码初始化器的终结器。

	Class<?> getEncodeType();

	Class<?> getDecodeType();

	Map<Object, Expression> getEncoderInitializer();

	Map<Object, Expression> getDecoderInitializer();

	Map<Object, Expression> getEncoderFinalizer();

	Map<Object, Expression> getDecoderFinalizer();

2.AbstractSerializerDef类
这个类从类名就可以看出来它的作用,它是implements SerializerDef的。实现这个接口,但是这里面的方法也都没有实现,因为它是一个抽象类。

	public void accept(Visitor visitor) {
    
    
	}
	public Set<Integer> getVersions() {
    
    
		return emptySet();
	}
	public boolean isInline(int version, CompatibilityLevel compatibilityLevel) {
    
    
		return true;
	}
	public Class<?> getDecodeType() {
    
    
		return getEncodeType();
	}
	public Map<Object, Expression> getEncoderInitializer() {
    
    
		return Collections.emptyMap();
	}
	public Map<Object, Expression> getDecoderInitializer() {
    
    
		return Collections.emptyMap();
	}
	public Map<Object, Expression> getEncoderFinalizer() {
    
    
		return Collections.emptyMap();
	}
	public Map<Object, Expression> getDecoderFinalizer() {
    
    
		return Collections.emptyMap();
	}

3.BinaryInput类
这个类提供从字节数组读取原语和字符串的方法。
可以从这个类中定义的属性可以看出,它是把byte数组当成容器,并且定义了一个pos变量,用来指出字符的位置。

	public final byte[] array;
	public int pos;

定义了两个构造方法,也是对定义的array的初始化。

	public BinaryInput(byte[] array) {
    
    
		this.array = array;
	}

	public BinaryInput(byte[] array, int pos) {
    
    
		this.array = array;
		this.pos = pos;
	}

从这个类的作用就可以知道,它是需要几个操作方法的,用来对array数组中的字符进行操作:

public byte[] array() {
    
    
		return array;
	}

	public int pos() {
    
    
		return pos;
	}

	public void pos(int pos) {
    
    
		this.pos = pos;
	}

	public void move(int delta) {
    
    
		this.pos += delta;
	}

	public int read(byte[] b) {
    
    
		return read(b, 0, b.length);
	}

	public int read(byte[] b, int off, int len) {
    
    
		System.arraycopy(this.array, pos, b, off, len);
		pos += len;
		return len;
	}

因为这个类是用来读取各种字符的,所以本类定义了许多的read方法,下面列举几个,还有很多就不一一列举了。

	public byte readByte() {
    
    
		return array[pos++];
	}

	public boolean readBoolean() {
    
    
		return readByte() != 0;
	}

	public short readShort() {
    
    
		short result = (short) ((array[pos] & 0xFF) << 8 | array[pos + 1] & 0xFF);
		pos += 2;
		return result;
	}

4.BinaryOutput类
这个类与BinaryInput类恰好相反,BinaryInput方法是提供从字节数组读取原语和字符串的方法。而BinaryOutput类是提供写入原语和字符串的方法。
构造函数和定义的属性与BinaryInput相同,那几个数组操作同样也是一样的,不过是定义了许多write方法,下面我们来看一下:

	public void write(byte[] bytes) {
    
    
		pos = BinaryOutputUtils.write(array, pos, bytes);
	}

	public void write(byte[] bytes, int bytesOff, int len) {
    
    
		pos = BinaryOutputUtils.write(array, pos, bytes, bytesOff, len);
	}

	public void writeBoolean(boolean v) {
    
    
		pos = BinaryOutputUtils.writeBoolean(array, pos, v);
	}

	public void writeByte(byte v) {
    
    
		pos = BinaryOutputUtils.writeByte(array, pos, v);
	}

	public void writeShort(short v) {
    
    
		pos = BinaryOutputUtils.writeShort(array, pos, v);
	}

需要注意的是,这个类中的write方法都调用了BinaryOutputUtils类中的write方法,这个类我会在之后介绍到。
5.BinarySerializer类
BinarySerializer类表示将值编码和解码为字节数组的序列化程序。但要注意它也是一个接口,虽然定义了方法但还没有实现。这个类定义了编码和解码方法,编码使用了BinaryOutput定义的对象,然后调用自己的encode方法;解码使用了BinaryInput定义的对象。

	default int encode(byte[] array, int pos, T item) {
    
    
		BinaryOutput out = new BinaryOutput(array, pos);
		encode(out, item);
		return out.pos();
	}

	default T decode(byte[] array, int pos) throws CorruptedDataException {
    
    
		return decode(new BinaryInput(array, pos));
	}

	void encode(BinaryOutput out, T item);

	T decode(BinaryInput in) throws CorruptedDataException;

四、总结

本次解读的代码时core-serializer中独立于几个包之外的类或接口,有些是其他类的依赖,有些是需要在其他类中实现的接口,都是比较重要的。其中一些类还是需要我们解读完那几个包中的代码才能更好地理解它的意思,因为有一些方法就是调用了那些宝包中的方法。

猜你喜欢

转载自blog.csdn.net/zth_idea/article/details/121342522