一文详解Java Netty中的Constant类
作者:KittyGuy 发布时间:2023-03-03 17:17:55
Constant
Constant 和 ConstantPool 是用于表示常量的一种机制。
Constant 接口定义了常量的基本属性和方法,包括唯一标识 ID、名称。
value就是Constant本身,确定范型的具体类型即可。
class Main {
public static void main(String[] args) {
MyConstant value = new MyConstant();
System.out.println(value.PI);
System.out.println(value.object);
}
static class MyConstant implements Constant<MyConstant> {
public double PI = 3.1415926;
public Object object = new Object();
private final int id;
private final String name;
public MyConstant() {
id = new Random().nextInt();
name = id + "#";
}
@Override
public int id() {
return id;
}
@Override
public String name() {
return name;
}
@Override
public int compareTo(MyConstant other) {
return Integer.compare(id, other.id);
}
}
}
但是一般通过ConstantPool进行管理。
注意范型T继承自Constant。
常量都是类的形式。
ChannelConfig
ChannelConfig是一个Channel的配置属性集合。请将其向下转换为更具体的配置类型,例如SocketChannelConfig,或使用setOptions(Map)来设置与传输相关的属性:
Channel ch = ...;
SocketChannelConfig cfg = (SocketChannelConfig) ch.getConfig();
cfg.setTcpNoDelay(false);
Option map是一个动态的只写属性,允许在不向下转换其关联的ChannelConfig的情况下配置一个Channel。
动态的只写属性是指,属性值可以在程序运行时动态地进行修改,但只能进行写操作,不能进行读操作。在Option map中,只提供了设置属性值的方法,没有提供获取属性值的方法,因此称之为只写属性。
不需要转型:
Channel ch = ...;
Map<ChannelOption<?>, Object> options = new HashMap<>();
options.put(ChannelOption.SO_TIMEOUT, 5000);
options.put(ChannelOption.SO_KEEPALIVE, true);
ch.config().setOptions(options);
//不需要SocketChannelConfig cfg = (SocketChannelConfig) ch.getConfig();
//所有Channel都可以用
要更新选项映射,请调用setOptions(Map)。所有的ChannelConfig都有以下选项:
名称 关联的设置方法
ChannelOption.CONNECT_TIMEOUT_MILLIS setConnectTimeoutMillis(int)
ChannelOption.WRITE_SPIN_COUNT setWriteSpinCount(int)
ChannelOption.WRITE_BUFFER_WATER_MARK setWriteBufferWaterMark(WriteBufferWaterMark)
ChannelOption.ALLOCATOR setAllocator(ByteBufAllocator)
ChannelOption.AUTO_READ setAutoRead(boolean)
在ChannelConfig的子类型中还有更多选项可用。例如,您可以根据SocketChannelConfig中所述的方式配置特定于TCP/IP套接字的参数。
要注意这些配置是真实存在的,不能乱配,UPD显然是没有保活机制的,就不能用
options.put(ChannelOption.SO_KEEPALIVE, true);
Netty中重要的Constant实现类:ChannelOption和AttributeKey
ChannelOption
该类就是以类型安全的方式配置ChannelConfig。
使用 ChannelOption 时可以通过编译器进行类型检查,从而避免在运行时出现类型错误的情况。
用例:
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress("example.com", 80))
// 使用 ChannelOption 配置连接超时时间
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
AttributeKey
注意这是Key,它是映射到Attribute的。
在Netty中,
Attribute
用于在Channel
中存储关联的元数据。可以将Attribute
看作是一个键值对,其中键是一个AttributeKey
类型的对象,而值是任意类型的Java对象。存储和获取连接的会话信息;
存储和获取连接的统计信息;
存储和获取连接的用户权限信息;
存储和获取连接的特定状态信息,如是否已经登录等。
Attribute
在网络应用中有着广泛的用途,例如:可以通过
Channel
的attr()
方法获取一个AttributeMap
对象,用于存储和获取Attribute
。其中,AttributeMap
是一个接口,其默认实现为DefaultAttributeMap
,可以使用它来操作Attribute
。用例:
public class MyHandler {
private final Attribute<AtomicInteger> messageCounterAttr;
public MyHandler(Channel channel) {
messageCounterAttr = channel.attr(AttributeKey.valueOf("messageCounter"));
messageCounterAttr.set(new AtomicInteger(0));
}
public void handle(Object msg) {
// increment message counter
AtomicInteger messageCounter = messageCounterAttr.get();
messageCounter.incrementAndGet();
// do other things with the message
// ...
}
}
源码学习
ConstantPool中的valueOf方法
第一次检测是为了避免重复创建,如果该常量已经存在,则直接返回该常量;第二次检测是为了保证多线程下的线程安全,只有当该常量不存在时才创建新的常量,如果另一个线程已经创建了该常量,则直接返回已创建的常量。
如果不使用双重检测,可能会出现多个线程同时创建相同名称的常量,导致产生多个相同的常量实例。因此,使用双重检测可以避免重复创建常量,并保证在多线程环境下的线程安全。
小结
Constant
类是 Netty 框架提供的用于实现常量池的类,通常用于框架内部的常量定义,而不是用于业务代码的常量定义。AttributeKey
和ChannelOption
都是 Netty 中用于为Channel
和ChannelConfig
存储属性的机制,它们的主要区别在于作用的范围和使用场景。ChannelOption
是一种可选配置项,它定义了ChannelConfig
可以使用的参数。ChannelOption
可以用于配置网络协议的底层参数,例如 SO_LINGER 或 TCP_NODELAY 等。通常情况下,
ChannelOption
用于设置连接参数,例如连接超时时间、Nagle 算法等。ChannelOption
是针对ChannelConfig
的,使用channel.config().setOption(option, value)
方法来设置。ChannelOption
适用于需要传递给 Netty 底层的配置参数。AttributeKey
则是用于在Channel
上存储一些属性,这些属性通常是业务逻辑相关的,例如登录用户、登录状态等。AttributeKey
对象是一个标识符,可以在Channel
上存储和访问一个属性值。与
ChannelOption
不同,AttributeKey
存储的属性是不透明的,Netty 不知道这些属性的含义,因为是自定义的。AttributeKey
适用于需要在业务逻辑中存储和访问数据的场景,例如在一个ChannelHandler
中存储和读取登录用户信息。Attribute
用于在Channel
中存储一些自定义的数据 ,这些数据可以被Channel
中的各个处理器共享和访问。
来源:https://juejin.cn/post/7229984415329878072


猜你喜欢
- 前言本文主要讲述如何在同一个窗体内,实现不同功能模块的页面切换。一、准备工作1.搭建一个简单的mvvm项目结构首先搭建一个简单的项目框架,然
- Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类:class Hello<T>(val value: T)val
- 这篇文章主要介绍了spring boot 2整合swagger-ui过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的
- 情况一:问题idea项目突然无法运行,提示找不到某个类。查看了编译输出目录out,发现没有class文件。尝试解决尝试删除out、重新导入项
- 一、在 AndroidManifest.xml文件中配置Widgets:<manifest xmlns:android="h
- 支持趋势线的图表类型包括二维面积图、条形图、柱形图、柱形图、股价图、xy (散点图) 和气泡图中;不能向三维、堆积、雷达图、饼图、曲面图或圆
- 已知字符串“aabbbcddddeeffffghijklmnopqrst”编程找出出现最多的字符和次数,要求时间复杂度小于O(n^2)/**
- 这篇文章主要介绍了Java向上转型和向下转型实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 一、背景SpringBoot 为我们快速开发提供了很好的架子,使得我们只需要少量配置就能开始我们的开发工作,但是当我们需要打包上传部署时,却
- 本文主要讲解如何通过RabbitMQ实现定时任务(延时队列)环境准备需要在MQ中进行安装插件 地址链接插件介绍地址:https://www.
- 要求环境信息:WIN2008SERVER 开发工具:VS2015 开发语言:C#要求: 1.点击同步数据后接口获取数
- java应用CPU有波动,事后怎么分析?目前我采用的方案是根据CPU负载自动执行jstack,并将文件上传到OSS。 环境:阿里云
- Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,
- 在生产环境中,需要实时或定期监控服务的可用性。spring-boot 的actuator(监控)功能提供了很多监控所需的接口。简单的配置和使
- 一、介绍SharpZipLib是一个完全由C#编写的ZIP,GZIP,Tar和BZIP2 Library,可以方便的支持这几种格式的压缩和解
- 固定的策略有时候还是无法满足千变万化的需求变动,一方面需要支持特定的用户需求,另一方面又得尽可能的复用代码,避免重复开发,这就需要将这部分的
- 一般来讲,项目更换JDK版本的情况比较少,但是有时难免会遇到。电脑安装不同版本的JDK这里不做介绍。这里记录一下修改项目JDK版本要注意的几
- 什么是JSON?JSON (JavaScript Object Notation) is a lightweight data-interc
- 首先说微信企业号的开发模式分为:编辑模式(普通模式)和开发模式(回调模式) ,在编辑模式下,只能做简单的自定义菜单和自动回复消息,要想实现其
- 首先说说什么叫回调函数?在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口