JEP 418:互联网地 址解析 SPI
概括
定义用于主机名和地址解析的服务提供商接口 (SPI),以便java.net.InetAddress
可以使用除平台内置解析器之外的解析器。
非目标
-
开发一个替代解析器以包含在 JDK 中并不是我们的目标。默认情况下将继续使用 JDK 的内置解析器。
-
SPI 的目标不是支持超出
InetAddress
API 要求的解析操作。 -
定义非阻塞或异步解析 API 不是目标。
动机
APIjava.net.InetAddress
将主机名解析为 Internet 协议 (IP) 地址,反之亦然。 API 当前使用操作系统的本机解析器,该解析器通常配置为使用本地hosts
文件和域名系统 (DNS) 的组合。
定义用于名称和地址解析的服务提供商接口的动机包括:
-
Project Loom — API 的解析操作
InetAddress
当前在操作系统调用中阻塞。对于 Loom 的用户模式虚拟线程来说,这是一个问题,因为它会阻止底层平台线程在等待解 析操作完成时为其他虚拟线程提供服务。另一种解析器可以直接实现 DNS 客户端协议,而不会阻塞。 -
新兴网络协议——解析器 SPI 将支持新解析协议的无缝集成,例如基于 QUIC、TLS 或 HTTPS 的 DNS。
-
定制——解析器 SPI 将使框架和应用程序能够更好地控制解析结果,并允许使用定制解析器对现有库进行改造。
-
测试- 原型设计和测试活动通常需要控制主机名和地址解析结果,例如在模拟使用 API 的组件时
InetAddress
。
描述
APIInetAddress
定义了多种查找操作方法:
-
InetAddress::getAllByName
执行_正向_查找,将主机名映射到一组 IP 地址。 -
InetAddress::getByName
还执行正向查找,将主机名映射到其地址集中的第一个地址。 -
InetAddress::getCanonicalHostName
执行_反向_查找,将 IP 地址映射到完全限定的域名。例如:var addressBytes = new byte[] { (byte) 192, 0, 43, 7};
var resolvedHostName = InetAddress.getByAddress(addressBytes)
.getCanonicalHostName(); -
InetAddress::getHostName
如果需要,还执行反向查找。
默认情况下,InetAddress
使用操作系统的本机解析器来执行查找。该查找的结果,无论是肯定的还是否定的,都可以被缓存以避免对同一主机的进一步查找。
服务提供商接口
APIInetAddress
将使用服务加载器来定位解析器提供者。如果找不到提供者,将像以前一样使用内置实现。
包中的新类java.net.spi
是:
-
InetAddressResolverProvider
— 定义要通过 定位的服务的抽象类java.util.ServiceLoader
。 AnInetAddressResolverProvider
本质上是一个解析器工厂。实例化的解析器将被设置为系统范围的解析器,并将InetAddress
所有查找请求委托给该解析器。 -
InetAddressResolver
— 定义基本正向和反向查找操作方法的接口。该接口的实例是从 的实例获得的InetAddressResolverProvider
。 -
InetAddressResolver.LookupPolicy
— 一个类,其实例描述解析请求的特征,包括请求的地址类型和返回地址的顺序。 -
InetAddressResolverProvider.Configuration
— 描述平台内置解析操作配置的接口。它提供对本地主机名和内置解析器的访问。自定义解析器提供程序使用它来引导解析器构建或将解析请求部分委托给操作系统的本机解析器。
备择方案
如果没有像此处建议的那样的 SPI,应用程序将不得不继续使用目前可用的解决方法。
-
应用程序可以使用 Java 命名和目录接口 (JNDI) 及其 DNS 提供程序来查找网络名称和地址。这种方法对于需要精细控制 DNS 查找的应用程序非常有用,但它与平台的网络 API 是解耦的
InetAddress
,因此与平台的网络 API 一起使用需要额外的工作。 -
应用程序可以通过 Java 本机接口 (JNI) 或来自巴拿马项目的外部函数 API直接使用操作系统的解析器库。然而,与 JNDI 一样,这种方法是解耦的,因此使用起来更加困难。
InetAddress
-
应用程序可以使用非标准的、特定于 JDK 的系统属性
jdk.net.hosts.file
来配置InetAddress
为使用特定文件(而不是操作系统的本机解析程序)将主机名映射到 IP 地址。此功能对于测试很有用,但它不是通用解决方案,因为并不总是事先知道完整的主机名列表。
测试
我们将为旋转变压器 SPI 开发新的测试。
我们将开发概念验证解析器提供程序来演示和验证 SPI 可用于开发和部署优先于 JDK 内置实现的替代实现。我们将至少提供这些提供商之一来为更完整的实施的开发提供种子。