这是我参与8月更文挑战的第十天,活动详情查看:8月更文挑战
我们来看一下大致的结构图
顶级接口DataBuffer
public interface DataBuffer {}
spring是这样描述 DataBuffer
的:
字节缓冲区的基本抽象。DataBuffers有一个独立的读写位置,而ByteBuffer只有一个位置。因此,DataBuffer在写入后不需要翻转读取。通常,以下不变式适用于读写位置和容量:0 <= readPosition <= writePosition <= capacity;DataBuffer的容量是按需扩展的,类似于StringBuilder。DataBuffer抽象的主要目的是为ByteBuffer提供一个方便的包装器,它类似于Netty的io.net .buffer. bytebuf,但也可以用于非Netty平台(例如Servlet容器)。
一句话就是,这个DataBuffer对ByteBuffer进行一个包装,使用时不仅仅包括servlet,也可以在网络编程中使用。
接着就是DataBufferFactory
// 提供DataBuffer接口的方便实现。
public interface DataBufferFactory {
// 根据底层配置,分配一个默认初始容量的数据缓冲区
DataBuffer allocateBuffer();
// 根据底层配置,分配一个指定初始容量的数据缓冲区
DataBuffer allocateBuffer(int initialCapacity);
// 将给定的ByteBuffer包装到DataBuffer中。与分配不同,包装不使用新的内存
DataBuffer wrap(ByteBuffer byteBuffer);
// 将给定的字节数组包装到DataBuffer中。与分配不同,包装不使用新的内存
DataBuffer wrap(byte[] bytes);
// 将多个databuffer组合成一个
DataBuffer join(List<? extends DataBuffer> dataBuffers);
最后我们来看看DataBuffer
的工具类DataBufferUtils
public abstract class DataBufferUtils {
private final static Log logger = LogFactory.getLog(DataBufferUtils.class);
// 表示接受单个输入参数而不返回结果的操作
private static final Consumer<DataBuffer> RELEASE_CONSUMER = DataBufferUtils::release;
// 根据InputStream,并将其读入databuffer的Flux中
public static Flux<DataBuffer> readInputStream(
Callable<InputStream> inputStreamSupplier, DataBufferFactory bufferFactory, int bufferSize) {
Assert.notNull(inputStreamSupplier, "'inputStreamSupplier' must not be null");
return readByteChannel(() -> Channels.newChannel(inputStreamSupplier.call()), bufferFactory, bufferSize);
}
// 根据ReadableByteChannel,并将其读入databuffer的Flux中
public static Flux<DataBuffer> readByteChannel(
Callable<ReadableByteChannel> channelSupplier, DataBufferFactory bufferFactory, int bufferSize) {
Assert.notNull(channelSupplier, "'channelSupplier' must not be null");
Assert.notNull(bufferFactory, "'dataBufferFactory' must not be null");
Assert.isTrue(bufferSize > 0, "'bufferSize' must be > 0");
return Flux.using(channelSupplier,
channel -> Flux.generate(new ReadableByteChannelGenerator(channel, bufferFactory, bufferSize)),
DataBufferUtils::closeChannel);
// No doOnDiscard as operators used do not cache
}
...
// 包括读、写、释放、join、matcher, 从 InputStream/NIO 读取DataBuffer对象的Flux的方法,
// 以及将数据缓冲区Flux写入OutputStream/Channel等方法。spring参考于反应式编程框架Reactor中的Flux
}