ActiveJ学习心得——serializer(6)

2021SC@SDUSC

一、代码分析内容

本次博客继续进行core-serializer包中imp包的分析,上一次分析了这个包的六个序列化定义的几个数据结构的类,本次我们再来分析一下剩下的7个类,它们是定义的其他一些数据结构的序列化定义。

二、impl包结构


本次分析的是SerializerDefClass类、SerializerDefCollection类、SerializerDefDouble类、SerializerDefEnum类、SerializerDefFloat类、SerializerDefInet4Address类、SerializerDefInet6Address类这7个类。

三、代码解读

1.SerializerDefClass类
此类继承AbstractSerializerDef类,这个是序列化定义类的类,说起来就像是套娃一样。从这个名字可以看出,这个类中要包含Class的一些功能,要将这些都进行Serialize操作。下面我们来看一下。此类定义的属性如下:

	private final Class<?> encodeType;
	private final Class<?> decodeType;
	private final LinkedHashMap<String, FieldDef> fields = new LinkedHashMap<>();

	private Constructor<?> constructor;
	private List<String> constructorParams;
	private Method factory;
	private List<String> factoryParams;
	private final Map<Method, List<String>> setters = new LinkedHashMap<>();

	private SerializerDefClass(Class<?> encodeType, Class<?> decodeType) {
		this.encodeType = encodeType;
		this.decodeType = decodeType;
	}

这里定义了encodeType、decodeType这两个编码和解码类型,下面这两个属性是要用到的。
我们看到constructor属性就是构造器,是进行要对构造方法的形式进行改变的。下面的constructorParams列表就是存储constructor的各种参数。
factory是工厂方法,它也有一个参数列表factoryParams。
下面是create方法,其作用是创建一个class所用的:

	public static SerializerDefClass create(@NotNull Class<?> type) {
		return new SerializerDefClass(type, type);
	}

	public static SerializerDefClass create(@NotNull Class<?> encodeType, @NotNull Class<?> decodeType) {
		if (!encodeType.isAssignableFrom(decodeType))
			throw new IllegalArgumentException(format("Class should be assignable from %s", decodeType));
		return new SerializerDefClass(encodeType, decodeType);
	}

下面几个方法就是对上述定义的属性进行的操作,当然,也是一个class所必需的。例如Setter和Getter方法等:

	public void addSetter(@NotNull Method method, @NotNull List<String> fields) {
		if (decodeType.isInterface())
			throw new IllegalStateException("Class should either implement an interface or be an interface");
		if (isPrivate(method.getModifiers()))
			throw new IllegalArgumentException(format("Setter cannot be private: %s", method));
		if (method.getGenericParameterTypes().length != fields.size())
			throw new IllegalArgumentException("Number of arguments of a method should match a size of list of fields");
		if (setters.containsKey(method)) throw new IllegalArgumentException("Setter has already been added");
		setters.put(method, fields);
	}
	public void addGetter(Method method, SerializerDef serializer, int added, int removed) {
		if (method.getGenericParameterTypes().length != 0)
			throw new IllegalArgumentException("Method should have 0 generic parameter types");
		if (!isPublic(method.getModifiers()))
			throw new IllegalArgumentException("Method should be public");
		String fieldName = stripGet(method.getName(), method.getReturnType());
		if (fields.containsKey(fieldName)) throw new IllegalArgumentException(format("Duplicate field '%s'", method));
		FieldDef fieldDef = new FieldDef();
		fieldDef.method = method;
		fieldDef.serializer = serializer;
		fieldDef.versionAdded = added;
		fieldDef.versionDeleted = removed;
		fields.put(fieldName, fieldDef);
	}

	public void setConstructor(@NotNull Constructor<?> constructor, @NotNull List<String> fields) {
		if (decodeType.isInterface())
			throw new IllegalStateException("Class should either implement an interface or be an interface");
		if (this.constructor != null)
			throw new IllegalArgumentException(format("Constructor is already set: %s", this.constructor));
		if (isPrivate(constructor.getModifiers()))
			throw new IllegalArgumentException(format("Constructor cannot be private: %s", constructor));
		if (constructor.getGenericParameterTypes().length != fields.size())
			throw new IllegalArgumentException("Number of arguments of a constructor should match a size of list of fields");
		this.constructor = constructor;
		this.constructorParams = fields;
	}

当然这个类里面也有专属于它的编码和解码方法。
2.SerializerDefCollection类
此类继承AbstractSerializerDefCollection类,AbstractSerializerDefCollection类是一个序列化定义Collection的类的一个抽象类,它的构造方法和重写方法如下:

	public SerializerDefCollection(SerializerDef valueSerializer, Class<?> encodeType, Class<?> decodeType) {
		this(valueSerializer, encodeType, decodeType, false);
	}

	private SerializerDefCollection(SerializerDef valueSerializer, Class<?> encodeType, Class<?> decodeType, boolean nullable) {
		super(valueSerializer, Collection.class, decodeType, Object.class, nullable);
	}

	@Override
	public SerializerDef ensureNullable(CompatibilityLevel compatibilityLevel) {
		if (compatibilityLevel.getLevel() < LEVEL_3.getLevel()) {
			return new SerializerDefNullable(this);
		}
		return new SerializerDefCollection(valueSerializer, encodeType, decodeType, true);
	}

这里重写的是ensureNullable方法,它是在ensureNullable类中出现的,而AbstractSerializerDefCollection类实现了ensureNullable类。
3.SerializerDefDouble类
此类继承了SerializerDefPrimitive类,这是上一次博客分析过的序列化定义原语的类。此类中ensureWrapped,doSerialize和doDeserialize方法都是继承自SerializerDefPrimitive类并且进行重写的。是为了定义有关Double的。doSerialize方法就是进行writeDouble,doDeserialize方法就是进行readDouble的。

	public SerializerDefDouble() {
		this(true);
	}

	public SerializerDefDouble(boolean wrapped) {
		super(double.class, wrapped);
	}

	@Override
	public SerializerDef ensureWrapped() {
		return new SerializerDefDouble(true);
	}

	@Override
	protected Expression doSerialize(Expression byteArray, Variable off, Expression value, CompatibilityLevel compatibilityLevel) {
		return writeDouble(byteArray, off, value, !compatibilityLevel.isLittleEndian());
	}

	@Override
	protected Expression doDeserialize(Expression in, CompatibilityLevel compatibilityLevel) {
		return readDouble(in, !compatibilityLevel.isLittleEndian());
	}

4.SerializerDefFloat类
这个类和上面的SerializerDefDouble类还是比较相似的,因为float和double都是基本的数据类型,所以序列化还是相对来说比较简单的。也就是在doSerialize和doDeserialize方法中使用的writeFloat和readFloat的不同。

	public SerializerDefFloat() {
		this(true);
	}

	public SerializerDefFloat(boolean wrapped) {
		super(float.class, wrapped);
	}

	@Override
	public SerializerDef ensureWrapped() {
		return new SerializerDefFloat(true);
	}

	@Override
	protected Expression doSerialize(Expression byteArray, Variable off, Expression value, CompatibilityLevel compatibilityLevel) {
		return writeFloat(byteArray, off, value, !compatibilityLevel.isLittleEndian());
	}

	@Override
	protected Expression doDeserialize(Expression in, CompatibilityLevel compatibilityLevel) {
		return readFloat(in, !compatibilityLevel.isLittleEndian());

5.SerializerDefEnum类
这是一个序列化定义枚举类型的类。枚举类型我们平时用的比较少,这个类继承AbstractSerializerDef类和SerializerDefWithNullable类。我们通过它定义的属性和构造方法中可以看出,它定义了枚举类型和是否可为空。

	private final Class<? extends Enum<?>> enumType;
	private final boolean nullable;

	public SerializerDefEnum(Class<? extends Enum<?>> enumType, boolean nullable) {
		this.enumType = enumType;
		this.nullable = nullable;
	}

下面是isSmallEnum方法,这个方法在此类的encoder和decoder方法中都有使用到。这个方法返回了Enum的大小,就像它的方法名一样,是一个小的枚举,我们可以看到,如果size >= 16384,就会抛出异常。

	private boolean isSmallEnum() {
		int size = enumType.getEnumConstants().length + (nullable ? 1 : 0);
		if (size >= 16384) throw new IllegalArgumentException();
		return size <= Byte.MAX_VALUE;
	}

6.SerializerDefInet4Address类
Inet4Address这个类是InetAddress的子类,它是java中有关IPv4的类。而SerializerDefInet4Address类就是序列化定义Inet4Address的。在getEncodeType方法中,返回的就是Inet4Address.class,而编码和解码方法是对读写字节进行处理,调用地址。

	@Override
	public Class<?> getEncodeType() {
		return Inet4Address.class;
	}

	@Override
	public Expression encoder(StaticEncoders staticEncoders, Expression buf, Variable pos, Expression value, int version, CompatibilityLevel compatibilityLevel) {
		return writeBytes(buf, pos, call(value, "getAddress"));
	}

	@Override
	public Expression decoder(StaticDecoders staticDecoders, Expression in, int version, CompatibilityLevel compatibilityLevel) {
		return let(arrayNew(byte[].class, value(4)), array ->
				sequence(
						readBytes(in, array),
						staticCall(getDecodeType(), "getByAddress", array)));
	}

7.SerializerDefInet6Address
这是有关IPv6的,和上面那个类基本一致,就是在decoder的let(arrayNew(byte[].class, value(16)),中value参数不一样。

	public Expression decoder(StaticDecoders staticDecoders, Expression in, int version, CompatibilityLevel compatibilityLevel) {
		return let(arrayNew(byte[].class, value(16)), array ->
				sequence(
						readBytes(in, array),
						staticCall(getDecodeType(), "getByAddress", nullRef(String.class), array, nullRef(NetworkInterface.class))));
	}

四、总结

本次博客分析的是impl的另外7个类,我认为上述的这几个类中,SerializerDefClass类是最重要的,因为它的层次是比较高的,而其他的几个就是定义一些数据类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值