hadoop中,组件配置是由Hadoop的Configuration的一个实例实现。(在源码包的org.apache.hadoop.conf中可以找到)先上个类图:这只是部分的,Configuraation涉及的方法很多,不一一例举了。

在这里面我们看到的是整个hadoop的核心包的conf package里面涉及到全部类和接口。

在书中,我们可以看到一个XML文档以及一个利用configuration实例来读取XML文档的程序。这里搬过来,方便下面的学习分析。

<?xml version="1.0"?>
<configuration>
<property>
<name>color</name>
<value>yellow</value>
<description>Color</description>
</property> <property>
<name>size</name>
<value>10</value>
<description>Size</description>
</property> <property>
<name>weight</name>
<value>heavy</value>
<final>true</final>
<description>Weight</description>
</property> <property>
<name>size-weight</name>
<value>${size},${weight}</value>
<description>Size and weight</description>
</property>
</configuration>

java实例代码如下:

    Configuration conf = new Configuration();
conf.addResource("configuration-1.xml");
assertThat(conf.get("color"), is("yellow"));
assertThat(conf.getInt("size", 0), is(10));
assertThat(conf.get("breadth", "wide"), is("wide"));

在这里我们主要首先关注一个get(String name)方法.

public String get(String name) {
return substituteVars(getProps().getProperty(name));
}

首先应该从addResource()说起,如conf.addResource("configuration-1.xml"),这里实现了类似懒加载的方法来实现资源的读取,也就是说在add完成XML文件的时候,是不会去更新属性列表的,只有当有需要读取属性值的时候才会进行资源的加载。要注意的是,在addResource()的时候,会将给定的资源放到一个资源private
ArrayList 里面,然后会调用reloadConfiguration方法:

public synchronized void reloadConfiguration() {
properties = null; // 清除之前加载进来的全部属性
finalParameters.clear(); // 因为可以在属性里面标注final属性,所以在这里可以将全部的final属性全部也清除掉。
}

读取属性的时候,就会先调用getProps()方法,这个方法里面调用了Configuration类里面的一个核心方法,loadResources():

private void loadResources(Properties properties, ArrayList resources, boolean quiet) {
//三个参数,properties用来存储加载出来的属性,resources表明资源列表, quiet表示静默模式,默认不会存储新加进来的资源文件,只会进行临时加载。
if(loadDefaults) {
for (String resource : defaultResources) {
loadResource(properties, resource, quiet);
} //support the hadoop-site.xml as a deprecated case
if(getResource("hadoop-site.xml")!=null) {
loadResource(properties, "hadoop-site.xml", quiet);
}
} for (Object resource : resources) {
loadResource(properties, resource, quiet);
}
}

这里提供了三张资源加载的方式,但是最后是由loadResource(properties, resource, quiet)这一方法来实现的。这里主要的实现是利用java DOM API 对所有的resource进行遍历,将全部的属性值加载到这里面来。初始化代码如下:

     DocumentBuilderFactory docBuilderFactory
= DocumentBuilderFactory.newInstance();
//实例化一个工厂类
      docBuilderFactory.setIgnoringComments(true);

      //忽略开头的命名空间等信息
docBuilderFactory.setNamespaceAware(true);
try {
docBuilderFactory.setXIncludeAware(true);
} catch (UnsupportedOperationException e) {
LOG.error("Failed to set setXIncludeAware(true) for parser "
+ docBuilderFactory
+ ":" + e,
e);
}
      DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
Document doc = null;
Element root = null;

因为有string url inputstream三种格式的参数传进来,前两种都会转成URL的形式送到builder.parse()来解析。

由上面大家也看到了,采用了DOM的解析方式。熟悉XML的人都知道,还有一种比较流行的解析方式,SAX解析。在这里,相对的XML文档不会太多,所以解析的效果也不会有明显的差异,都是可行的。但是DOM的解析方式更为的直观、直接。

部分的for循环当中的代码:

        NodeList fields = prop.getChildNodes();
String attr = null;
String value = null;
boolean finalParameter = false;
for (int j = 0; j < fields.getLength(); j++) {
Node fieldNode = fields.item(j);
if (!(fieldNode instanceof Element))
continue;
Element field = (Element)fieldNode;
if ("name".equals(field.getTagName()) && field.hasChildNodes())
attr = ((Text)field.getFirstChild()).getData().trim();
if ("value".equals(field.getTagName()) && field.hasChildNodes())
value = ((Text)field.getFirstChild()).getData();
if ("final".equals(field.getTagName()) && field.hasChildNodes())
finalParameter = "true".equals(((Text)field.getFirstChild()).getData());
}

最后经过

properties.setProperty(attr, value);

放入结合当中,这样就产生了get()方法调用substituteVars方法的getPros()的方法。

在学习上述的代码的时候,我慢慢体会到了,java私有方法和公有方法的一些使用的要点。那就是在使用私有方法的时候,应该尽可能的降低其对于全局变量的依赖性,可以在调用私有方法前尽可能的去掉一些不要的逻辑,让私有方法好好的工作。像configuration这个类,从addResource到loadResource,都是极尽可能的消除方法后端的一些影响因素,将更多的逻辑分担出来,使得代码的阅读更加的简单明了,这是一个程序员应该有的品质吧。

最后要说一下,这里面还有一个用于属性导出的函数,也是一个比较值得学习的方法,这里就把代码贴出来。

public static void dumpConfiguration(Configuration conf,
Writer out) throws IOException {
Configuration config = new Configuration(conf,true);
config.reloadConfiguration();
JsonFactory dumpFactory = new JsonFactory();
JsonGenerator dumpGenerator = dumpFactory.createJsonGenerator(out);
dumpGenerator.writeStartObject();
dumpGenerator.writeFieldName("properties");
dumpGenerator.writeStartArray();
dumpGenerator.flush();
for (Map.Entry<Object,Object> item: config.getProps().entrySet()) {
dumpGenerator.writeStartObject();
dumpGenerator.writeStringField("key", (String) item.getKey());
dumpGenerator.writeStringField("value",
config.get((String) item.getKey()));
dumpGenerator.writeBooleanField("isFinal",
config.finalParameters.contains(item.getKey()));
dumpGenerator.writeStringField("resource",
config.updatingResource.get(item.getKey()));
dumpGenerator.writeEndObject();
}
dumpGenerator.writeEndArray();
dumpGenerator.writeEndObject();
dumpGenerator.flush();
}

configuration类详解的更多相关文章

  1. JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表

    一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...

  2. Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解

    1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...

  3. Java基础-DBCP连接池(BasicDataSource类)详解

    Java基础-DBCP连接池(BasicDataSource类)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程 ...

  4. java之StringBuffer类详解

    StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...

  5. java之AbstractStringBuilder类详解

    目录 AbstractStringBuilder类 字段 构造器 方法   public abstract String toString() 扩充容量 void  expandCapacity(in ...

  6. java之StringBuilder类详解

    StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...

  7. Java String类详解

    Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...

  8. QAction类详解:

    先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...

  9. C# 内置 DateTime类详解

    C# 内置 DateTime类详解 摘抄自微软官方文档,用来方便自己查阅:网址:https://msdn.microsoft.com/zh-cn/library/system.datetime(v=v ...

随机推荐

  1. Spoj-DWARFLOG Manipulate Dwarfs

    Manipulate Dwarfs In a small village beyond seven hills and seven seas, Snow White lives together wi ...

  2. spring 找不到applicationContext.xml解决方法

    初学Spring在用Resource rs=new ClassPathResource("applicationContext.xml");时老是遇到这个错误.后来发现用Appli ...

  3. ActivityGroup中监听返回按键

    如果你想使用ActivityGroup来统一管理Activity的话,当然首先这是一种很好的方法,但是如果你想在ActivityGroup里面拦截返回按键来进行统一管理的话,直接覆写onKeyDown ...

  4. Codeforces 667D World Tour【最短路+枚举】

    垃圾csdn,累感不爱! 题目链接: http://codeforces.com/contest/667/problem/D 题意: 在有向图中找到四个点,使得这些点之间的最短距离之和最大. 分析: ...

  5. koa2 从入门到进阶之路 (一)

    首先我们先来了解一下 Koa 是什么,https://koa.bootcss.com/,这是 Koa 的官方网站,映入眼帘的第一句就是 Koa -- 基于 Node.js 平台的下一代 web 开发框 ...

  6. 1861 奶牛的数字游戏 2006年USACO

    codevs——1861 奶牛的数字游戏 2006年USACO  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题解       题目描述 Descript ...

  7. 【Java TCP/IP Socket】UDP Socket(含代码)

    UDP的Java支持 UDP协议提供的服务不同于TCP协议的端到端服务,它是面向非连接的,属不可靠协议,UDP套接字在使用前不需要进行连接.实际上,UDP协议只实现了两个功能: 1)在IP协议的基础上 ...

  8. oracle存储过程中使用字符串拼接

    1.使用拼接符号“||” v_sql := 'SELECT * FROM UserInfo WHERE ISDELETED = 0 AND ACCOUNT =''' || vAccount || '' ...

  9. 普元OA平台介绍

    Primeton Portal提供了访问企业信息资源的统一入口,是一个面向企业的内容管理.信息发布和集成展现平台,提供了单点登录.内容管理.信息发布.应用集成.个性化等功能,能够帮助企业快速搭建一个集 ...

  10. Linux索引节点(Inode:no space for device)用满导致的一次故障

    问题描写叙述 在storm測试环境集群上上nimbus和supervisor自己主动挂调.重新启动时显示no space for device,也不能创建,加入文件及文件夹,df -h查看 ilesy ...