实现接口
public interface Marshaller {
/**
* Sets marshaller context.
*
* @param ctx Marshaller context.
*/
public void setContext(MarshallerContext ctx);
/**
* Marshals object to the output stream. This method should not close
* given output stream.
*
* @param obj Object to marshal.
* @param out Output stream to marshal into.
* @throws IgniteCheckedException If marshalling failed.
*/
public void marshal(@Nullable Object obj, OutputStream out) throws IgniteCheckedException;
/**
* Marshals object to byte array.
*
* @param obj Object to marshal.
* @return Byte array.
* @throws IgniteCheckedException If marshalling failed.
*/
public byte[] marshal(@Nullable Object obj) throws IgniteCheckedException;
/**
* Unmarshals object from the input stream using given class loader.
* This method should not close given input stream.
*
* @param Type of unmarshalled object.
* @param in Input stream.
* @param clsLdr Class loader to use.
* @return Unmarshalled object.
* @throws IgniteCheckedException If unmarshalling failed.
*/
public T unmarshal(InputStream in, @Nullable ClassLoader clsLdr) throws IgniteCheckedException;
/**
* Unmarshals object from byte array using given class loader.
*
* @param Type of unmarshalled object.
* @param arr Byte array.
* @param clsLdr Class loader to use.
* @return Unmarshalled object.
* @throws IgniteCheckedException If unmarshalling failed.
*/
public T unmarshal(byte[] arr, @Nullable ClassLoader clsLdr) throws IgniteCheckedException;
}
最终实现是调用 org.apache.ignite.internal.binary.GridBinaryMarshaller中的方法
序列化方法
/**
* @param obj Object to marshal.
* @param failIfUnregistered Throw exception if class isn't registered.
* @return Byte array.
* @throws org.apache.ignite.binary.BinaryObjectException In case of error.
*/
public byte[] marshal(@Nullable Object obj, boolean failIfUnregistered) throws BinaryObjectException {
if (obj == null)
return new byte[] { NULL };
try (BinaryWriterExImpl writer = new BinaryWriterExImpl(ctx)) {
writer.failIfUnregistered(failIfUnregistered);
writer.marshal(obj);
return writer.array();
}
}
反序列化
/**
* @param arr Byte array.
* @param ldr Class loader.
* @return Deserialized object.
* @throws org.apache.ignite.binary.BinaryObjectException In case of error.
*/
@SuppressWarnings("unchecked")
@Nullable public T deserialize(byte[] arr, @Nullable ClassLoader ldr) throws BinaryObjectException {
assert arr != null;
assert arr.length > 0;
if (arr[0] == NULL)
return null;
BinaryContext oldCtx = pushContext(ctx);
try {
return (T)new BinaryReaderExImpl(ctx, BinaryHeapInputStream.create(arr, 0), ldr, true).deserialize();
}
finally {
popContext(oldCtx);
}
}
这里面引入2个类 BinaryWriterExImpl, BinaryReaderExImpl
往里面走
GridBinaryMarshaller.deserialize
(T)new BinaryReaderExImpl(ctx, BinaryHeapInputStream.create(arr, 0), ldr, true).deserialize()
case OPTM_MARSH:
obj = BinaryUtils.doReadOptimized(in, ctx, ldr);
ctx.optimizedMarsh().unmarshal(input, U.resolveClassLoader(clsLdr, ctx.configuration())) -> unmarshal0
ctx.optiomizedMarsh() = OptimizedMarshaller
return (T)objIn.readObject();
objIn = OptimizedObjectInputStream -> readObject0() -> case HANDLE:
return handles.lookup(readInt());
OptimizedObjectInputStream
这段代码比较特殊
case HANDLE:
return handles.lookup(readInt());
handles = HandleTable
是handle类型的,直接取数据
这个handle类型的意思是, 如果是使用优化方式的序列化, 在遇到相同字符的时候,只会记录一个数字,而不需要把整个字符都重复记录一遍, 这样大大节省了空间, 这要求读跟写都遵循这套方法, 才能正确解出数据
TcpDiscoveryNode [id=8164f1e1-ff3f-4d6f-bdc5-d9615339d292, addrs=[0:0:0:0:0:0:0:1, 127.0.0.1, 192.168.120.80], sockAddrs=[WLPF15J9DQ.wks.jnj.com/192.168.120.80:47501, /0:0:0:0:0:0:0:1:47501, /127.0.0.1:47501], discPort=47501, order=2, intOrder=2, lastExchangeTime=1555666131881, loc=false, ver=2.7.0#20181201-sha1:256ae401, isClient=false]
下面分析一下序列化
OptimizedObjectOutputStream.writeObject0
待续