Live2D

spring官网在线学习文档翻译8

8. Data Buffers and Codecs(数据缓冲区和编解码器)

8.1. Introduction(入门)

The DataBuffer interface defines an abstraction over byte buffers. The main reason for introducing it, and not use the standard java.nio.ByteBuffer instead, is Netty. Netty does not use ByteBuffer, but instead offers ByteBuf as an alternative. Spring’s DataBuffer is a simple abstraction over ByteBuf that can also be used on non-Netty platforms (i.e. Servlet 3.1+).

  • DataBuffer接口在字节缓冲区上定义了一个抽象。引入它的主要原因,而不是使用标准java.nio。字节缓冲区相反,是Netty。Netty不使用ByteBuffer,而是提供ByteBuf作为替代。Spring的DataBuffer是ByteBuf上的一个简单抽象,也可以在非网络平台(即Servlet 3.1+)上使用。

8.2. DataBufferFactory

The DataBufferFactory offers functionality to allocate new data buffers, as well as to wrap existing data. The allocate methods allocate a new data buffer, with a default or given capacity. Though DataBuffer implementation grow and shrink on demand, it is more efficient to give the capacity upfront, if known. The wrap methods decorate an existing ByteBuffer or byte array. Wrapping does not involve allocation: it simply decorates the given data with a DataBuffer implementation.

  • DataBufferFactory提供了分配新数据缓冲区以及包装现有数据的功能。分配方法使用默认或给定的容量分配新的数据缓冲区。尽管DataBuffer的实现会随需增减,但如果已知,提前提供容量会更有效。包装方法修饰现有的ByteBuffer或字节数组。包装不涉及分配:它只是使用DataBuffer实现来装饰给定的数据

There are two implementation of DataBufferFactory: the NettyDataBufferFactory which is meant to be used on Netty platforms, such as Reactor Netty. The other implementation, the DefaultDataBufferFactory, is used on other platforms, such as Servlet 3.1+ servers.

  • DataBufferFactory有两个实现:NettyDataBufferFactory,用于网络平台上,比如Reactor Netty。另一个实现DefaultDataBufferFactory用于其他平台,比如Servlet 3.1+服务器。

8.3. The DataBuffer interface(DataBuffer接口)

The DataBuffer interface is similar to ByteBuffer, but offers a number of advantages. Similar to Netty’s ByteBuf, the DataBuffer abstraction offers independent read and write positions. This is different from the JDK’s ByteBuffer, which only exposes one position for both reading and writing, and a separate flip() operation to switch between the two I/O operations. In general, the following invariant holds for the read position, write position, and the capacity:

-DataBuffer接口与ByteBuffer类似,但是提供了许多优点。与Netty的ByteBuf类似,DataBuffer抽象提供了独立的读和写位置。这与JDK的ByteBuffer不同,后者只公开一个读取和写入位置,以及一个单独的flip()操作,用于在两个I/O操作之间切换。一般情况下,读位置、写位置和容量不变:

0 <= read position <= write position <= capacity

When reading bytes from the DataBuffer, the read position is automatically updated in accordance with the amount of data read from the buffer. Similarly, when writing bytes to the DataBuffer, the write position is updated with the amount of data written to the buffer. Also, when writing data, the capacity of a DataBuffer is automatically expanded, just like StringBuilder, ArrayList, and similar types.

  • 当从DataBuffer读取字节时,读取位置会根据从缓冲区读取的数据量自动更新。类似地,当向DataBuffer写入字节时,写入位置会随着写入缓冲区的数据量而更新。另外,在写入数据时,DataBuffer的容量会自动扩展,就像StringBuilder、ArrayList和类似类型一样。

Besides the reading and writing functionality mentioned above, the DataBuffer also has methods to view a (slice of a) buffer as ByteBuffer, InputStream, or OutputStream. Additionally, it offers methods to determine the index of a given byte.

  • 除了上面提到的读写功能,DataBuffer还具有将缓冲区的(部分)查看为ByteBuffer、InputStream或OutputStream的方法。此外,它还提供了确定给定字节索引的方法。

There are two implementation of DataBuffer: the NettyDataBuffer which is meant to be used on Netty platforms, such as Reactor Netty. The other implementation, the DefaultDataBuffer, is used on other platforms, such as Servlet 3.1+ servers.

  • DataBuffer有两个实现:NettyDataBuffer,它用于网络平台,比如Reactor Netty。另一个实现DefaultDataBuffer用于其他平台,比如Servlet 3.1+服务器。

8.3.1. PooledDataBuffer

The PooledDataBuffer is an extension to DataBuffer that adds methods for reference counting. The retain method increases the reference count by one. The release method decreases the count by one, and releases the buffer’s memory when the count reaches 0. Both of these methods are related to reference counting, a mechanism that is explained below.

  • PooledDataBuffer是DataBuffer的扩展,它添加了用于引用计数的方法。retain方法将引用计数增加1。release方法将计数减少1,并在计数达到0时释放缓冲区的内存。这两种方法都与引用计数有关,这是下面解释的一种机制。

Note that DataBufferUtils offers useful utility methods for releasing and retaining pooled data buffers. These methods take a plain DataBuffer as parameter, but only call retain or release if the passed data buffer is an instance of PooledDataBuffer.

  • 注意,DataBufferUtils提供了有用的实用工具方法来释放和保留池数据缓冲区。这些方法采用普通的DataBuffer作为参数,但是只有在传递的数据缓冲区是PooledDataBuffer的实例时才调用retain或release。
Reference Counting(引用计数)

Reference counting is not a common technique in Java; it is much more common in other programming languages such as Object C and C++. In and of itself, reference counting is not complex: it basically involves tracking the number of references that apply to an object. The reference count of a PooledDataBuffer starts at 1, is incremented by calling retain, and decremented by calling release. As long as the buffer’s reference count is larger than 0 the buffer will not be released. When the number decreases to 0, the instance will be released. In practice, this means that the reserved memory captured by the buffer will be returned back to the memory pool, ready to be used for future allocations.

  • 引用计数不是Java中常见的技术;它在其他编程语言中更常见,比如对象C和c++。引用计数本身并不复杂:它主要涉及跟踪应用于对象的引用的数量。PooledDataBuffer的引用计数从1开始,通过调用retain递增,通过调用release递减。只要缓冲区的引用计数大于0,缓冲区就不会被释放。当数量减少到0时,该实例将被释放。在实践中,这意味着由缓冲区捕获的保留内存将返回到内存池,准备用于未来的分配。

In general, the last component to access a DataBuffer is responsible for releasing it. Withing Spring, there are two sorts of components that release buffers: decoders and transports. Decoders are responsible for transforming a stream of buffers into other types (see Codecs below), and transports are responsible for sending buffers across a network boundary, typically as an HTTP message. This means that if you allocate data buffers for the purpose of putting them into an outbound HTTP message (i.e. client-side request or server-side response), they do not have to be released. The other consequence of this rule is that if you allocate data buffers that do not end up in the body, for instance because of a thrown exception, you will have to release them yourself. The following snippet shows a typical DataBuffer usage scenario when dealing with methods that throw exceptions:

  • 通常,访问DataBuffer的最后一个组件负责释放它。在Spring中,有两种组件可以释放缓冲区:解码器和传输。解码器负责将缓冲区流转换为其他类型(参见下面的编解码器),而传输则负责跨网络边界发送缓冲区,通常是作为HTTP消息发送。这意味着,如果你分配数据缓冲区的目的是把它们放入一个出站HTTP消息(即客户端请求或服务器端响应),它们不必被释放。此规则的另一个后果是,如果您分配的数据缓冲区没有在体中结束,例如由于抛出异常,您将必须自己释放它们。下面的代码片段显示了处理抛出异常的方法时典型的DataBuffer使用场景
DataBufferFactory factory = ...
DataBuffer buffer = factory.allocateBuffer(); 
boolean release = true; 
try {
    writeDataToBuffer(buffer); 
    putBufferInHttpBody(buffer);
    release = false; 
}
finally {
    if (release) {
        DataBufferUtils.release(buffer); 
    }
}

private void writeDataToBuffer(DataBuffer buffer) throws IOException { 
    ...
}
A new buffer is allocated.(分配一个新的缓冲区。)
A boolean flag indicates whether the allocated buffer should be released.(布尔标志指示是否应该释放已分配的缓冲区。)
This example method loads data into the buffer. Note that the method can throw an IOException, and therefore a finally block to release the buffer is required.(这个示例方法将数据加载到缓冲区中。注意,该方法可以抛出一个IOException,因此需要一个finally块来释放缓冲区。)
If no exception occurred, we switch the release flag to false as the buffer will now be released as part of sending the HTTP body across the wire.(如果没有发生异常,我们将释放标志切换为false,因为缓冲区现在将作为通过网络发送HTTP主体的一部分被释放。)
If an exception did occur, the flag is still set to true, and the buffer will be released here.(如果发生异常,该标志仍然设置为true,缓冲区将在这里释放。)

8.3.2. DataBufferUtils

DataBufferUtils contains various utility methods that operate on data buffers. It contains methods for reading a Flux of DataBuffer objects from an InputStream or NIO Channel, and methods for writing a data buffer Flux to an OutputStream or Channel. DataBufferUtils also exposes retain and release methods that operate on plain DataBuffer instances (so that casting to a PooledDataBuffer is not required).

  • DataBufferUtils包含在数据缓冲区上操作的各种实用工具方法。它包含用于从InputStream或NIO通道读取DataBuffer对象流量的方法,以及用于将数据缓冲区流量写入OutputStream或通道的方法。DataBufferUtils还公开在普通DataBuffer实例上操作的保留和释放方法(因此不需要强制转换为PooledDataBuffer)。

Additionally, DataBufferUtils exposes compose, which merges a stream of data buffers into one. For instance, this method can be used to convert the entire HTTP body into a single buffer (and from that, a String, or InputStream). This is particularly useful when dealing with older, blocking APIs. Note, however, that this puts the entire body in memory, and therefore uses more memory than a pure streaming solution would.

  • 此外,DataBufferUtils公开组合,后者将数据缓冲区流合并为一个缓冲区。例如,此方法可用于将整个HTTP主体转换为单个缓冲区(并由此转换为字符串或InputStream)。这在处理较旧的阻塞api时特别有用。但是请注意,这将整个主体放在内存中,因此比纯粹的流解决方案使用更多的内存。

Codecs(编译解码器)

The org.springframework.core.codec package contains the two main abstractions for converting a stream of bytes into a stream of objects, or vice-versa. The Encoder is a strategy interface that encodes a stream of objects into an output stream of data buffers. The Decoder does the reverse: it turns a stream of data buffers into a stream of objects. Note that a decoder instance needs to consider reference counting.

  • org.springframework.core。编解码器包包含两个主要的抽象转换字节流到对象流,或反之亦然。编码器是一个策略接口,它将对象流编码为数据缓冲区的输出流。译码器则相反:它将数据缓冲区的流转换为对象流。请注意,解码器实例需要考虑引用计数。

Spring comes with a wide array of default codecs, capable of converting from/to String, ByteBuffer, byte arrays, and also codecs that support marshalling libraries such as JAXB and Jackson (with Jackson 2.9+ support for non-blocking parsing). Withing the context of Spring WebFlux, codecs are used to convert the request body into a @RequestMapping parameter, or to convert the return type into the response body that is sent back to the client. The default codecs are configured in the WebFluxConfigurationSupport class, and can easily be changed by overriding the configureHttpMessageCodecs when inheriting from that class. For more information about using codecs in WebFlux, see this section.

  • Spring提供了大量的默认编解码器,能够从字符串、字节缓冲区、字节数组转换为字符串、字节数组,还提供了支持编组库(如JAXB和Jackson)的编解码器(Jackson 2.9+支持非阻塞解析)。在Spring WebFlux的上下文中,编解码器用于将请求体转换为@RequestMapping参数,或者将返回类型转换为发送回客户端的响应体。默认的编解码器是在WebFluxConfigurationSupport类中配置的,并且可以在继承该类时通过覆盖configureHttpMessageCodecs轻松地进行更改。有关在WebFlux中使用编解码器的更多信息,请参见本节。

后续戳^

posted @ 2020-09-29 10:52  六爻呈乾  阅读(227)  评论(0编辑  收藏  举报