spirng framework源码解析之spring-core-Databuffer(十)

721 阅读1分钟

这是我参与8月更文挑战的第十天,活动详情查看:8月更文挑战

我们来看一下大致的结构图

DataBuffer.png

顶级接口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
}