Dubbo编解码系列文章目录
Dubbo编解码(一)-原理
Dubbo编解码(二)-Codec2和AbstractCodec
Dubbo编解码(三)-TransportCodec
Dubbo编解码(五)-Dubbo协议编码器
Dubbo编解码(六)-Dubbo协议解码器
文章目录
TransportCodec-传输层编解码
继承了 抽象类AbstractCodec
实现了 扩展点接口Codec2的encode和decode方法
encode
@Override
public void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException {
OutputStream output = new ChannelBufferOutputStream(buffer);
// 把 字节输出流-output 写入到 对象输出-objectOutput 里面
// 序列化,所有serialize方法的具体实现 的 返回对象,都实现了ObjectOutput接口,ex: Hessian2ObjectOutput
// 针对序列化扩展点的serialize方法后面整理
ObjectOutput objectOutput = getSerialization(channel).serialize(channel.getUrl(), output);
encodeData(channel, objectOutput, message);
objectOutput.flushBuffer();
if (objectOutput instanceof Cleanable) {
((Cleanable) objectOutput).cleanup();
}
}
decode
@Override
public Object decode(Channel channel, ChannelBuffer buffer) throws IOException {
InputStream input = new ChannelBufferInputStream(buffer);
// 反序列化
ObjectInput objectInput = getSerialization(channel).deserialize(channel.getUrl(), input);
Object object = decodeData(channel, objectInput);
if (objectInput instanceof Cleanable) {
((Cleanable) objectInput).cleanup();
}
return object;
}
encodeData和decodeData
TransportCodec 还定义了encodeData、decodeData
ObjectOutput、ObjectInput的具体实现分别是ChannelBufferOutputStream、ChannelBufferInputStream
protected void encodeData(Channel channel, ObjectOutput output, Object message) throws IOException {
encodeData(output, message);
}
protected void encodeData(ObjectOutput output, Object message) throws IOException {
// 对应ObjectOutput具体实现类的writeObject方法
output.writeObject(message);
}
protected Object decodeData(Channel channel, ObjectInput input) throws IOException {
return decodeData(input);
}
protected Object decodeData(ObjectInput input) throws IOException {
try {
// 对应ObjectInput具体实现类的readObject方法
return input.readObject();
} catch (ClassNotFoundException e) {
throw new IOException("ClassNotFoundException: " + StringUtils.toString(e));
}
}
ChannelBufferOutputStream-通道缓存输出流
主要作用就是针对ChannelBuffer的写操作做封装
ChannelBufferOutputStream继承了抽象类OutputStream
针对抽象类OutputStream的具体实现和覆写 都是使用 ChannelBuffer#writeBytes
所以 外部调用ChannelBufferOutputStream#write 其实就是 操作 ChannelBuffer#writeBytes
成员变量
private final ChannelBuffer buffer;
private final int startIndex;
构造方法
public ChannelBufferOutputStream(ChannelBuffer buffer) {
if (buffer == null) {
throw new NullPointerException("buffer");
}
this.buffer = buffer;
// 用buffer的写索引writerIndex初始化startIndex
startIndex = buffer.writerIndex();
}
覆写、实现OutputStream
// 覆写
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (len == 0) {
return;
}
// TODO 涉及Netty源码
buffer.writeBytes(b, off, len);
}
@Override
public void write(byte[] b) throws IOException {
buffer.writeBytes(b);
}
// 实现
@Override
public void write(int b) throws IOException {
buffer.writeByte((byte) b);
}
ChannelBufferInputStream-通道缓存输入流
和ChannelBufferOutputStream类似
成员变量
private final ChannelBuffer buffer;
private final int startIndex;
private final int endIndex;
构造方法
public ChannelBufferInputStream(ChannelBuffer buffer) {
// buffer.readableBytes() = 写索引位置 - 读索引位置
this(buffer, buffer.readableBytes());
}
public ChannelBufferInputStream(ChannelBuffer buffer, int length) {
// ...
this.buffer = buffer;
// 起始位置 = 读索引位置
startIndex = buffer.readerIndex();
// 结束位置 = 读索引位置 + (写索引位置 - 读索引位置)
endIndex = startIndex + length;
// 标记读索引
buffer.markReaderIndex();
}
覆写、实现InputStream
// 覆写
@Override
public int available() throws IOException {
// 是否可读 = 结束位置 - 当前读索引位置
return endIndex - buffer.readerIndex();
}
@Override
public void mark(int readlimit) {
// 对当前readerIndex做标记
buffer.markReaderIndex();
}
@Override
public boolean markSupported() {
return true;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int available = available();
if (available == 0) {
return -1;
}
// 取 可读长度 和 准备读取长度 的 较小值
len = Math.min(available, len);
buffer.readBytes(b, off, len);
return len;
}
@Override
public void reset() throws IOException {
// 重置 buffer的读索引位置 = markedReaderIndex
buffer.resetReaderIndex();
}
@Override
public long skip(long n) throws IOException {
if (n > Integer.MAX_VALUE) {
return skipBytes(Integer.MAX_VALUE);
} else {
return skipBytes((int) n);
}
}
private int skipBytes(int n) throws IOException {
int nBytes = Math.min(available(), n);
// 跳过指定长度的字节,就是将readerIndex设置为 当前readerIndex+n,并且不能超过当前writerIndex
buffer.skipBytes(nBytes);
// 返回跳过的字节数
return nBytes;
}
// 实现
@Override
public int read() throws IOException {
// 如果buffer不可读,也就是可读字节数<0
if (!buffer.readable()) {
return -1;
}
// 读取一个字节
return buffer.readByte() & 0xff;
}