在java.net包描述中, 简要说明了一些关键的接口. 其中负责networking identifiers的是Addresses. 这个类的具体实现类是InetAddress, 底层封装了Inet4Address与Inet6Address的异同, 可以看成一个Facade工具类.

  1. A Low Level API, which deals with the following abstractions:
  2. Addresses, which are networking identifiers, like IP addresses.
  3. Sockets, which are basic bidirectional data communication mechanisms.
  4. Interfaces, which describe network interfaces.

复制代码

在OpenJDK的InetAddress源码中, 根据dns或hostname解析IP的代码部分:

  1. private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)
  2. throws UnknownHostException  {
  3. /* If it gets here it is presumed to be a hostname */
  4. /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  5. /* make sure the connection to the host is allowed, before we
  6. * give out a hostname
  7. */
  8. if (check) {
  9. SecurityManager security = System.getSecurityManager();
  10. if (security != null) {
  11. security.checkConnect(host, -1);
  12. }
  13. }
  14. InetAddress[] addresses = getCachedAddresses(host);
  15. /* If no entry in cache, then do the host lookup */
  16. if (addresses == null) {
  17. addresses = getAddressesFromNameService(host, reqAddr);
  18. }
  19. if (addresses == unknown_array)
  20. throw new UnknownHostException(host);
  21. return addresses.clone();
  22. }

复制代码

关键的二个方法是:
getCachedAddresses(host);
getAddressesFromNameService(host, reqAddr);
前者从addressCache, 或negativeCache根据dns/hostname解析缓存的IP.
后者从遍历nameServices,调用每个NameService的lookupAllHostAddr(host)查找IP, 然后将host:IP缓存到前面的cache中.
根据上述, 实现动态解析DNS, 有二种方式:
1. 反射addressCache, 或negativeCache, 将host:IP通过Cache的put()方法放入.
2. 反射nameServices,将代理的NameService实例放入.
二种做法的难处:
1. addressCache, 或negativeCache都是 java.net.InetAddress.Cache, 其内部的CacheEntry受二组JVM选项影响:
networkaddress.cache.ttl
networkaddress.cache.negative.ttl
在ttl后, CacheEntry的get()只会返回null.
2. nameServices只是OpenJDK的实现. 换言之,只是SUN一家的. 其他JDK不用此属性名.
写段代码看看Jrockit与IBM JVM中InetAddress内部的属性:

  1. Class<InetAddress> type = InetAddress.class;
  2. Field[] fields = type.getDeclaredFields();
  3. for (Field f : fields) {
  4. System.out.println(f.getName() + ":" + f.getType());
  5. }

复制代码

OpenJDK:

  1. IPv4
  2. IPv6
  3. preferIPv6Address
  4. holder
  5. nameServices
  6. canonicalHostName
  7. serialVersionUID
  8. addressCache
  9. negativeCache
  10. addressCacheInit
  11. unknown_array
  12. impl
  13. lookupTable
  14. cachedLocalHost
  15. cacheTime
  16. maxCacheTime
  17. cacheLock
  18. FIELDS_OFFSET
  19. UNSAFE
  20. serialPersistentFields
  21. $assertionsDisabled

复制代码

JRockit:

  1. IPv4
  2. IPv6
  3. preferIPv6Address
  4. hostName
  5. address
  6. family
  7. nameService
  8. canonicalHostName
  9. serialVersionUID
  10. addressCache
  11. negativeCache
  12. addressCacheInit
  13. unknown_array
  14. impl
  15. lookupTable
  16. $assertionsDisabled

复制代码

IBM JDK

  1. IPv4:int
  2. IPv6:int
  3. preferIPv6Address
  4. hostName:class java.lang.String
  5. address:int
  6. family:int
  7. nameService:interface sun.net.spi.nameservice.NameService
  8. canonicalHostName:class java.lang.String
  9. serialVersionUID:long
  10. addressCache:class java.net.InetAddress$Cache
  11. negativeCache:class java.net.InetAddress$Cache
  12. localHostName:class java.lang.String
  13. localHostNameLock:class java.lang.Object
  14. cacheLocalHost:boolean
  15. addressCacheInit:boolean
  16. unknown_array:class [Ljava.net.InetAddress;
  17. impl:interface java.net.InetAddressImpl
  18. lookupTable:class java.util.HashMap
  19. $assertionsDisabled:boolean

复制代码

看到这里, 知道蛋疼了吧. 三种JDK中,
OpenJDK中是nameservices是个List<NameService>,
Jrockit与IBM JVM中却是nameservice, 只是单独的NameService实例.
所以要用第2种做法, 你至少要满足这三种主流JDK的需求.
简单实现二种做法:
做法1, 动态替换AddressCache.
做法2, 动态代理NameService.
源码如下

  1. 长度限制, 源码查看回贴.

复制代码

暂时测试到这吧, 有兴趣的同学可以一起完善. 争取同时满足OpenJDK, Jrockit, IBM JDK三种主流环境的DNS动态解析类.

Java动态替换InetAddress中DNS的做法简单分析1的更多相关文章

  1. Java动态替换InetAddress中DNS的做法简单分析2

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...

  2. java itext替换PDF中的文本

    itext没有提供直接替换PDF文本的接口,我们可以通过在原有的文本区域覆盖一个遮挡层,再在上面加上文本来实现. 所需jar包: 1.先在PDF需要替换的位置覆盖一个白色遮挡层(颜色可根据PDF文字背 ...

  3. Java动态代理——框架中的应用场景和基本原理

    前言 之前已经用了5篇文章完整解释了java动态代理的原理,本文将会为这个系列补上最后一块拼图,展示java动态代理的使用方式和应用场景 主要分为以下4个部分 1.为什么要使用java动态代理 2.如 ...

  4. MessageFormat的用法,java动态替换String字符串中的占位符

    import java.text.MessageFormat; import java.util.GregorianCalendar; import java.util.Locale; public ...

  5. 【Android】通过Java代码替换TabHost中的drawableTop资源

    在博客 http://blog.csdn.net/jueblog/article/details/11837445 中的Tab选项卡中, 点击相应的Tab选项,图标没有发生改变. 这些资源图片也没有尽 ...

  6. Java动态调用类中方法

    在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...

  7. Java 动态向 JTable 中添加数据

    import java.awt.Toolkit; import javax.swing.SwingUtilities; import javax.swing.UIManager; import jav ...

  8. java.util.ComparableTimSort中的sort()方法简单分析

    TimSort算法是一种起源于归并排序和插入排序的混合排序算法,设计初衷是为了在真实世界中的各种数据中能够有较好的性能. 该算法最初是由Tim Peters于2002年在Python语言中提出的. T ...

  9. java获取properties配置文件中某个属性最简单方法

    假如我想获取src目录下sysConfig.properties中的uploadpath属性的值 方法如下所示: private static final ResourceBundle bundle ...

随机推荐

  1. rsync安装使用

    安装 yum install rsync mkdir /etc/rsyncd cd /etc/rsyncd vi rsyncd.conf pid file = /var/run/rsyncd.pid ...

  2. c语言将2进制数转化为10进制数(栈的初始化,进栈,出栈)

    //c语言描述 将2进制转化为10进制 #include <stdio.h> #include <stdlib.h> #include <math.h> #defi ...

  3. java.lang.Exception: Socket bind failed: [730013] An attempt was made to acc

    在CMD命令行中启动运行startup.bat,启运程序总是闪退,查看日志发现如下错误: 26-Jan-2016 18:12:34.463 SEVERE [main] org.apache.coyot ...

  4. ASP.NET MVC4 学习系统一(项目模板)

    项目模板 1.空模板      空模板用于创建ASP.NETMVC 4网站的架构,包含基本的文件夹结构,以及需要引用的asp.netmvc程序集,也包含可能要使用的javaScript 库.模板同样包 ...

  5. Windows Server 2012下安装Hyper-V虚拟机

    Windows Server 2012下安装Hyper-V虚拟机 Win server 2012系统中Hyper-V 性能进一步提高,广大爱好者都尝试体验它,可是有不少朋友无法正确安装虚拟机,尽管在网 ...

  6. 新安装的ubuntu系统如何设置中文输入法的方案

    本文是本人写的第一篇的linux博客,因为很菜,所以就把刚才自己安装中文输入法的过程给大家介绍一下,希望有所帮助. 1.首先,打开命令终端,两种方式,在Dash里面输入terminal然后enter, ...

  7. SVN与TortoiseSVN实战:文件加锁详解

    硬广:<SVN与TortoiseSVN实战>系列已经写了八篇,本篇是完结篇,整个系列结合TortoiseSVN对SVN中容易被忽视的部分进行了详解,以技巧性为主. 本篇详解使用Tortoi ...

  8. Loadrunner:error -86401 Failed to connceted xxx.xxx.xxx.xxx:25问题解决

    [转自:http://www.51testing.com/html/00/130600-3578408.html]windows 2003上安装的LoadRunner11做为负载机在SMTP协议压测时 ...

  9. Solaris引导和关闭

    OpenBoot PROM简称OBP,相当于PC的BIOS,是控制SUN服务器的引导过程.初始化配置某些硬件并提供某些诊断的工具.常见OBP命令 boot boot:从默认设备启动boot -s:从默 ...

  10. js,jquery获取下拉框选中的option

    js获取select选中的值: var sel=document.getElementById("select1"); var index = sel.selectedIndex; ...