hadoop源码学习(一)--configuration类详解
来源:互联网 发布:淘宝实战培训 编辑:程序博客网 时间:2024/05/22 15:11
学习hadoop也有一段时间了,本来一直在dataguru的日志系统上写一些学习工作的总结,但是比较的随意,没有太多的总结性。到最后因为那边的编辑系统不太好使,就决定转过来了。好了,废话少说,开始开源的hadoop项目源码学习旅途。
这个系列的博客将根据《hadoop权威指南》(第三版)的第五章开始,逐步分析学习文章中第一次出现的类。
第五章开始,就是Configuration,那就从这里入手。
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,都是极尽可能的消除方法后端的一些影响因素,将更多的逻辑分担出来,使得代码的阅读更加的简单明了,这是一个程序员应该有的品质吧。
最后要说一下,这里面还有一个用于属性导出的函数,也是一个比较值得学习的方法,这里就把代码贴出来。
- hadoop源码学习(一)--configuration类详解
- (一)hadoop源码学习之Configuration
- Hadoop Configuration 源码详解
- Hadoop源码分析笔记(一):Hadoop Configuration详解
- (二)hadoop源码学习之Configuration
- Hadoop源码之Configuration类
- hadoop Configured Configrable Configuration Tool 源码详解
- Hadoop源码学习(一)
- Mybatis源码分析(一)- Configuration配置文件详解
- Hadoop HDFS源码学习笔记(一)
- 【Hadoop源码学习】之hdfs(一)
- Hadoop学习(二)wordcount源码详解
- hadoop源码解析—— conf包中Configuration.java解析(一)
- Hadoop源码详解 前言(一)
- 2.2 Hadoop Configuration详解
- Hadoop Configuration详解
- Hadoop Configuration详解
- Hadoop Configuration详解
- NOJ 5533 c语言
- 处理elasticsearch中的NODENOTAVAILABLEEXCEPTIONS异常
- Oracle数据库中插入日期型数据
- android 进度条设置显示格式
- 自己实现LinkedListJAVA103-104
- hadoop源码学习(一)--configuration类详解
- 小记2015-11-9
- 零长度数组解析
- NOJ 5538 c语言
- Linux进程间通信——使用信号量
- 面向业务的立体化高可用架构设计
- 《leetCode》:Multiply Strings
- 编程之美-求数组中最长递增子序列(LIS)方法整理
- OC数组冒泡排序