🍊
翻译橙
🍊返回主站🤖参与贡献
  • hello,这里是翻译橙
  • spring boot参考文档
    • 1. 法律
    • 2. 寻求帮助
    • 3. 文档概述
    • 4. 入门
    • 5. 升级Spring Boot
    • 6. 使用 Spring Boot 进行开发
      • 6.1. 构建系统
      • 6.2. 构建你的代码
      • 6.3. 配置类
      • 6.4. 自动配置
      • 6.5. Spring Bean 和依赖注入
      • 6.6. 使用@SpringBootApplication注解
      • 6.7. 运行您的应用程序
      • 6.8. 开发者工具
      • 6.9. 打包您的生产应用程序
      • 6.10. 接下来读什么
    • 7.核心特性
      • 7.1. SpringApplication
      • 7.2. 外部化配置
      • 7.3.Profile配置
      • 7.4.日志记录
      • 7.5.国际化
      • 7.6 面向切面的编程
      • 7.7. JSON
      • 7.8. 任务执行与调度
      • 7.9. 单元测试
        • 7.9.1. 测试范围依赖
        • 7.9.2. 测试 Spring 应用程序
        • 7.9.3. 测试 Spring Boot 应用程序
        • 7.9.4. 测试容器
        • 7.9.5. 测试工具
      • 7.10. Docker Compose 支持
      • 7.11. 测试容器支持
      • 7.12. 创建您自己的自动配置
      • 7.13. Kotlin 支持
      • 7.14 SSL
      • 7.15.接下来要读什么
    • 8. 网络
      • 8.1. Servlet Web 应用程序
        • 8.1.1. “Spring Web MVC 框架”
        • 8.1.2. JAX-RS 和Jersey
        • 8.1.3. 嵌入式 Servlet 容器支持
      • 8.2 反应式网络应用程序
        • 8.2.1. “Spring WebFlux 框架”
        • 8.2.2. 嵌入式反应式服务器支持
        • 8.2.3. 反应式服务器资源配置
      • 8.3. 优雅关机
      • 8.4. spring安全
        • 8.4.1. MVC安全
        • 8.4.2. WebFlux 安全
        • 8.4.3. OAuth2
        • 8.4.4. SAML 2.0
      • 8.5. spring 会话
      • 8.6.GraphQL
      • 8.7. Spring HATEOAS
      • 8.8.接下来读什么
    • 9. 数据
      • 9.1. SQL数据库
      • 9.2. 使用 NoSQL 技术
      • 9.3. 接下来读什么
    • 10. 消息
      • 10.1. JMS
      • 10.2. AMQP
      • 10.3. Apache Kafka 支持
      • 10.4. Apache Pulsar 支持
      • 10.5. RSocket
      • 10.6. Spring Integration
      • 10.7. WebSockets
      • 10.8. What to Read Next
    • 11. IO
      • 11.1. 缓存
      • 11.2. Hazelcast
      • 11.3. Quartz 调度程序
      • 11.4. 发送电子邮件
      • 11.5. 验证
      • 11.6. 调用 REST 服务
      • 11.7. web services
      • 11.8. 使用 JTA 进行分布式事务
      • 11.9. 接下来读什么
    • 12. 容器镜像
  • Spring核心功能
    • 1.IOC容器和Bean简介
      • 1.2. 容器概述
      • 1.3. Bean概述
      • 1.4. 依赖项
        • 1.4.1. 依赖注入
        • 1.4.2. 详细的依赖关系和配置
        • 1.4.3. 使用depends-on
        • 1.4.4. 延迟初始化的 Bean
        • 1.4.5. 自动装配协作者
        • 1.4.6. 方法注入
    • 2. Resources
      • 2.1. 介绍
      • 2.2. Resource接口
      • 2.3. 内置Resource实现
      • 2.4. ResourceLoader接口
      • 2.5. ResourcePatternResolver接口
      • 2.6. ResourceLoaderAware接口
      • 2.7. 资源作为依赖
      • 2.8. 应用程序上下文和资源路径
    • 3. 验证、数据绑定和类型转换
      • 3.1. 使用 Spring 的 Validator 接口进行验证
      • 3.2. 将代码解析为错误消息
      • 3.3. Bean 操作和BeanWrapper
      • 3.4. spring类型转换
      • 3.5. spring字段格式
      • 3.6. 配置全局日期和时间格式
      • 3.7. Java Bean 验证
    • 4. SpEL表达式
    • 5. Spring 面向切面编程
      • 5.1. AOP 概念
      • 5.2. Spring AOP 的能力和目标
      • 5.3. AOP 代理
      • 5.4. @AspectJ 支持
        • 5.4.1. 启用@AspectJ 支持
        • 5.4.2. 声明一个切面
        • 5.4.3. 声明切入点
        • 5.4.4. 声明切点
        • 5.4.5. 切面说明
        • 5.4.6. 切面实例化模型
        • 5.4.7. AOP 示例
      • 5.5. 基于模式的 AOP 支持
      • 5.6. 选择要使用的 AOP 声明样式
      • 5.7. 混合切面类型
      • 5.8. 代理机制
      • 5.9. @AspectJ 代理的程序化创建
      • 5.10. 在 Spring 应用程序中使用 AspectJ
      • 5.11.更多资源
    • 6. Spring AOP API
      • 6.1. Spring中的切入点API
      • 6.2. Spring 中的 Advice API
      • 6.3. Spring 中的 Advisor API
      • 6.4. 使用ProxyFactoryBean创建 AOP 代理
      • 6.5. 简洁的代理定义
      • 6.6. 以编程方式创建 AOP 代理ProxyFactory
      • 6.7. 操作切面对象
      • 6.8. 使用“自动代理”工具
      • 6.9. 使用TargetSource实现
      • 6.10. 定义新的切面类型
    • 7. 空指针安全
    • 8. 数据缓冲器和编解码器
    • 9. 日志
    • 10. 附录
      • 10.1. XML 模式
      • 10.2. 自定义XML Schema
        • 10.2.1. 创作 Schema
        • 10.2.2. 编码一个NamespaceHandler
        • 10.2.3. 使用BeanDefinitionParser
        • 10.2.4. 注册处理程序和模式
        • 10.2.5. 在 Spring XML 配置中使用自定义扩展
        • 10.2.6. 更详细的例子
      • 10.3. 应用程序启动步骤
  • 使用redis实现分布式锁
  • Java 安全标准算法名称
  • JDK 9 JEP
  • JDK 10 JEP
  • 人件
    • 《人件》
    • 第一部分 管理人力资源
      • 01 此时此刻,一个项目正在走向失败
      • 02 干酪汉堡,做一个,卖一个
      • 03 维也纳在等你
      • 04 质量——如果时间允许
      • 05 再谈帕金森定律
      • 06 苦杏素
    • 第二部分 办公环境
      • 07 家具警察
      • 08 “朝九晚五在这里啥也完成不了。”
      • 09 在空间上省钱
      • 间奏曲:生产效率度量和不明飞行物
      • 10 大脑时问与身体时间
      • 11 电话
      • 12 门的回归
      • 13 采取保护步骤
    • 第三部分 正确的人
      • 14 霍恩布洛尔因素
      • 15 谈谈领导力
      • 16 雇一名杂耍演员
      • 17 与他人良好合作
      • 18 童年的终结
      • 19 在这儿很开心
      • 20 人力资本
    • 第四部分 高效团队养成
      • 21 整体大于部分之和
      • 22 黑衣团队
      • 23 团队自毁
      • 24 再谈团队自毁
      • 25 竞争
      • 26 一顿意面晚餐
      • 27 敞开和服
      • 28 团队形成的化学反应
    • 第五部分 沃土
      • 29 自我愈复系统
      • 30 与风险共舞
      • 3l 会议、独白和交流
      • 32 终极管理罪恶得主是……
      • 33 “邪恶”电邮
      • 34 让改变成为可能
      • 35 组织型学习
      • 36 构建社区
    • 第六部分 快乐地工作
      • 37 混乱与秩序
      • 38 自由电子
      • 39 霍尔加·丹斯克
由 GitBook 提供支持
在本页

这有帮助吗?

在GitHub上编辑
  1. Spring核心功能

8. 数据缓冲器和编解码器

上一页7. 空指针安全下一页9. 日志

最后更新于1年前

这有帮助吗?

Java NIO 提供了ByteBuffer但许多库在其上构建自己的字节缓冲区 API,特别是对于重用缓冲区和/或使用直接缓冲区有利于性能的网络操作。例如,Netty 有ByteBuf层次结构,Undertow 使用 XNIO,Jetty 使用池化字节缓冲区和要释放的回调,等等。spring-core模块提供了一组抽象来处理各种字节缓冲区 API,如下所示:

  • 抽象数据缓冲区的创建。

  • 表示一个字节缓冲区,它可以被 。

  • 为数据缓冲区提供实用方法。

  • 解码器将数据缓冲区流解码或编码为更高级别的对象。

8.1. DataBufferFactory

DataBufferFactory用于通过以下两种方式之一创建数据缓冲区:

  1. 分配一个新的数据缓冲区,如果知道的话,可以选择预先指定容量,即使实现DataBuffer可以按需增长和缩小,这也会更有效。

  2. 包装现有的byte[]或 java.nio.ByteBuffer,它使用DataBuffer实现装饰给定数据并且不涉及分配。

请注意,WebFlux 应用程序不会直接创建 DataBufferFactory ,而是通过客户端上的ServerHttpResponse或ClientHttpRequest访问它。工厂的类型取决于底层的客户端或服务器,例如对于 Reactor Netty是 NettyDataBufferFactory,对于其他的是DefaultDataBufferFactory。

8.2. DataBuffer

DataBuffer 接口提供与java.nio.ByteBuffer类似的操作,但还带来了一些额外的好处,其中一些好处是受到 Netty ByteBuf 的启发。以下是部分功能列表:

  • 以独立位置读取和写入,即不需要调用flip()来在读取和写入之间交替。

  • 容量随需扩展java.lang.StringBuilder。

  • 通过池化缓冲区和引用计数

  • 将缓冲区视为java.nio.ByteBuffer、InputStream或OutputStream。

  • 确定给定字节的索引或最后一个索引。

8.3.PooledDataBuffer

PooledDataBuffer是它的扩展,DataBuffer它有助于引用计数,这对于字节缓冲池至关重要。它是如何工作的?当 aPooledDataBuffer被分配时,引用计数为 1。调用retain()递增计数,调用release()递减计数。只要计数大于0,就保证缓冲区不会被释放。当计数减少到 0 时,可以释放池化缓冲区,这实际上可能意味着为缓冲区保留的内存返回到内存池。

请注意,PooledDataBuffer与其直接操作,在大多数情况下,最好使用DataBufferUtils应用版本中的便捷方法或 DataBuffer仅当它是PooledDataBuffer.

8.4.DataBufferUtils

DataBufferUtils提供了许多实用方法来操作数据缓冲区:

  • 如果底层字节缓冲区 API 支持,则将数据缓冲区流加入可能具有零副本的单个缓冲区,例如通过复合缓冲区。

  • 将InputStream或 NIOChannel变为Flux<DataBuffer>,反之亦然, Publisher<DataBuffer>变为OutputStream或 NIO Channel。

  • 如果缓冲区是 PooledDataBuffer的实例,则释放或保留 DataBuffer的方法。

  • 跳过或从字节流中获取,直到特定的字节数。

8.5.编解码器

org.springframework.core.codec包提供以下策略接口:

  • Encoder:编码Publisher<T>成数据缓冲区流。

  • Decoder:解码Publisher<DataBuffer>成更高级别的对象流。

8.6. 使用DataBuffer

Decoder是在创建更高级别对象之前最后读取输入数据缓冲区的,因此它必须按如下方式释放它们:

  1. 如果 Decoder简单地读取每个输入缓冲区并准备立即释放它,它可以通过DataBufferUtils.release(dataBuffer)方法.

  2. 如果 Decoder正在使用Flux或Mono操作符,例如flatMap, reduce,以及其他在内部预取和缓存数据项,或者正在使用操作符,例如 filter, skip,以及其他遗漏项,则 doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release)方法必须被添加到组合链中以确保这些缓冲区在之前被释放被丢弃,也可能是由于错误或取消信号。

  3. 如果 Decoder以任何其他方式保留一个或多个数据缓冲区,则必须确保在完全读取时释放它们,或者在缓存数据缓冲区被读取和释放之前发生错误或取消信号的情况下。

请注意,DataBufferUtils#join提供了一种将数据缓冲区流聚合到单个数据缓冲区中的安全有效的方法。同样skipUntilByteCount和 takeUntilByteCount是解码器使用的其他安全方法。

Encoder分配了其他必须读取(和释放)的数据缓冲区。所以 Encoder 没有什么可做的。但是,如果在用数据填充缓冲区时发生序列化错误,则Encoder必须注意释放数据缓冲区。例如:

DataBuffer buffer = factory.allocateBuffer();
boolean release = true;
try {
    // serialize and populate buffer..
    release = false;
}
finally {
    if (release) {
        DataBufferUtils.release(buffer);
    }
}
return buffer;

Encoder的消费者负责释放它接收到的数据缓冲区。在 WebFlux 应用程序中,Encoder的输出用于写入 HTTP 服务器响应或客户端 HTTP 请求,在这种情况下,释放数据缓冲区是写入服务器响应或客户端请求的代码的责任.

正如 的 Javadoc 中所解释的,字节缓冲区可以是直接的或非直接的。直接缓冲区可以驻留在 Java 堆之外,这消除了对本地 I/O 操作进行复制的需要。这使得直接缓冲区对于通过套接字接收和发送数据特别有用,但它们的创建和释放成本也更高,这导致了池化缓冲区的想法。

spring-core模块提供byte[]、ByteBuffer、DataBuffer、Resource和 String编码器和解码器实现。spring-web模块添加了 Jackson JSON、Jackson Smile、JAXB2、Protocol Buffers 和其他编码器和解码器。请参阅 WebFlux 部分中的

使用数据缓冲区时,必须特别注意确保缓冲区被释放,因为它们可能被。我们将使用编解码器来说明它是如何工作的,但这些概念更普遍适用。让我们看看编解码器必须在内部做什么来管理数据缓冲区。

请注意,在 Netty 上运行时,有用于 的调试选项。

DataBufferFactory
DataBuffer
池化
DataBufferUtils
codes
PooledDataBuffer
ByteBuffer
编解码器。
池化
解决缓冲区泄漏问题