Hadoop 2.6.0 Configuration源码分析

本文深入介绍了Hadoop2.6.0中Configuration类的功能,包括如何加载和存储XML配置文件中的键值对,以及如何处理Final参数。同时,还详细解释了类初始化和实例初始化的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在Hadoop 2.6.0中,Configuration类的作用主要提供配置参数的相关信息。其中定义了一个内部类Resource用来存放相应的单个xml配置文件的可达信息(包括String、Path、URL、InputStram、Properties、Element等),并从xml文件中解析出来的键值对存放在Properties对象中。

介绍

1.资源

  Configuration中配置信息由相关的xml配置文件指定,而xml配置文件中由一系列键值对组成,因此Configuration的主要功能即使找到这些xml配置文件,并且加载至类中。此时涉及两个问题,即如何加载和如何存放。首先Configuration内部定义了一个Resource类来存放xml配置文件的可达信息,包括String、Path、URL、InputStram、Properties、Element等,通过这些可达信息,就能找到相应的xml文件的具体位置,接下来便是通过Java进行xml解析,从而得到xml中的键值对的信息。在得到键值对后就是如何存放的问题了,在Configuration内部有一个Properties类的字段,分别将这些键值对存放到该对象当中即可。
  当Configuration类被加载时,会默认初始化core-default.xml和core-site.xml这两个配置文件。

2.Final参数

  在Configuration类中的参数可以被声明为Final类型,其中Final类型类似于Java中的final的用处,即不允许用户修改被声明为final类型的键对应的值。声明的方法就是在xml文件中在相应的配置参数中添加 < final > true< /final > 标签即可。

初始化过程

  初始化过程包括类初始化过程和实例初始化过程。首先当Java虚拟机加载该类时会进行类初始化,而之后当创建该类具体的对象时会进行实例初始化。Configuration中的初始化过程中,只会将相应的xml文件可达路径保存在Resource对象中,并不会马上进行xml的解析。只有当调用该对象的get*方法时,若检测到Properties字段为空时,才会进行xml解析,并把相应的键值对存放到Properties对象中去。

类初始化过程

static{
    //print deprecation warning if hadoop-site.xml is found in classpath
    ClassLoader cL = Thread.currentThread().getContextClassLoader();
    if (cL == null) {
      cL = Configuration.class.getClassLoader();
    }
    if(cL.getResource("hadoop-site.xml")!=null) {
      LOG.warn("DEPRECATED: hadoop-site.xml found in the classpath. " +
          "Usage of hadoop-site.xml is deprecated. Instead use core-site.xml, "
          + "mapred-site.xml and hdfs-site.xml to override properties of " +
          "core-default.xml, mapred-default.xml and hdfs-default.xml " +
          "respectively");
    }
    addDefaultResource("core-default.xml");
    addDefaultResource("core-site.xml");
}

这是一个静态初始化块,当Java虚拟机加载该类时,首先会调用该初始化块。从初始化块中可以看到,一开始会取得类加载器ClassLoader,通过这个类加载器寻找是否存在hadoop-site.xml,若存在就会发出一条警告,因为这个配置文件是老版本的文件,而现在的版本已不再这样命名。接着会调用静态方法addDefaultResource加载core-default.xml和core-site.xml(并不会对xml文件进行解析)。

public static synchronized void addDefaultResource(String name) {
  if(!defaultResources.contains(name)) {
    defaultResources.add(name);
    for(Configuration conf : REGISTRY.keySet()) {
      if(conf.loadDefaults) {
        conf.reloadConfiguration();
      }
    }
  }
}

上面addDefaultResource静态方法中,包含两个静态类变量:defaultResources(属于CopyOnWriteArrayList<String>类)和REGISTRY(属于WeakHashMap<Configuration,Object>类)。布尔变量loadDefaults用于确定是否加载默认资源。该方法作用即是判断defaultResources中是否含有name这个值,若没有就添加进去。REGISTRY存放的为具体的已经实例化的Configuration对象,在后面实例初始化时创建的对象会放入REGISTRY中。后面半部分代码表示当调用addDefaultResource这个静态方法时,并且之前创建的Configuration对象的loadDefaults字段为true时,会将properties(存放具体键值对)赋值为null,并且将finalParameters内的数据清空,finalParameters是一个HashSet类,用来存放声明了final的参数。

实例初始化过程

private ClassLoader classLoader;
{
  classLoader = Thread.currentThread().getContextClassLoader();
  if (classLoader == null) {
    classLoader = Configuration.class.getClassLoader();
  }
}

上面方法意思很直白,就是获得一个类加载器classLoader,并赋给成员变量。

public Configuration() {
  this(true);
}

public Configuration(boolean loadDefaults) {
  this.loadDefaults = loadDefaults;
  updatingResource = new HashMap<String, String[]>();
  synchronized(Configuration.class) {
    REGISTRY.put(this, null);
  }
}

上面代码为Configuration的构造器,十分的简单,可以注意到REGISTRY.put(this, null)这条语句,当每次实例化一个对象时,都会将自己注册到REGISTRY中去。
  到此为止,所有的初始化过程就结束了。但是可以看到当中并没有任何解析xml文件中键值对的相应的语句。这是因为在初始化时,只是简单的将xml的文件名保存下来,只有当调用该对象中的get*的语句时,才会进行xml的解析,并将解析后的值保存到properties当中去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值