Hadoop Configuration配置类的分析(三)

2015-01-27 06:00:05 · 作者: · 浏览: 21
,因为有的时候,通过这样的操作还无法取出真正想要的值。比如下面这样的结构:

           
    
            
             dfs.secondary.namenode.kerberos.principal
            
    
            
             hdfs/_HOST@${local.realm}
            
    
            
              Kerberos principal name for the secondary NameNode. 
            
  
           
也许你会直接通过dfs.secondary.namenode.kerberos.principal这个name去获取值,然后获取的值就是hdfs/_HOST@${local.realm},但是很显然这不是我们需要的值,因为中间还有${local.realm},这个其实代表的是另外的一个设置的值,有的时候更多的是系统变量的值,所以这一点告诉我们,在值的查找操作里面我们需要替换这些变量。

/**
   * Get the value of the name property, null if
   * no such property exists.
   * 
   * Values are processed for variable expansion 
   * before being returned. 
   * 
   * @param name the property name.
   * @return the value of the name property, 
   *         or null if no such property exists.
   */
  public String get(String name) {
    return substituteVars(getProps().getProperty(name));
  }
所以Hadoop在获取值后又进行了一步值替换的操作,用到了正则表达式。

//需匹配的模式为\$\{[^\}\$ ]+\},里面多的\是在java里进行转义
  //$,{,}是正则表达式中的保留字,因此需要加\,此匹配可分解为
  //'\$\'{匹配的是${的部分
  //最后的'\}'匹配了结尾符},这样就构成了初步的${....}的目标类型结构了
  //中间[^\}\$ ]匹配了除了},$,空格除外的关键字
  //+是1个修饰次数,保证中间的匹配至少为1次,也就是说中间至少有值存在
  private static Pattern varPat = Pattern.compile("\\$\\{[^\\}\\$\u0020]+\\}");
  private static int MAX_SUBST = 20;

  private String substituteVars(String expr) {
	//输入的属性匹配值,为空的话直接返回
    if (expr == null) {
      return null;
    }
    Matcher match = varPat.matcher("");
    String eva l = expr;
    //避免循环迭代陷入死循环,这里强制最多MAX_SUBST20次的替换
    for(int s=0; s
           
            系统变量
        val = System.getProperty(var);
      } catch(SecurityException se) {
        LOG.warn("Unexpected SecurityException in Configuration", se);
      }
      if (val == null) {
        val = getRaw(var);
      }
      if (val == null) {
        return eva l; // return literal ${var}: var is unbound
      }
      // substitute
      //然后取出对应的值进行替换,再次查找是否有${..}类型值的存在
      eva l = eva l.substring(0, match.start())+val+eva l.substring(match.end());
    }
    throw new IllegalStateException("Variable substitution depth too large: " 
                                    + MAX_SUBST + " " + expr);
  }
           
关键的难点是对于${...}这种模式的匹配器的构造,像我这种平时对于正则表达式第一想到的是上网找的人来说,就比较难想到了。还有1个特殊处理就是为了避免替换之后还会存在${...}出现死循环,所以这里有次数的限制。get操作的实现就是如此。最后看看我对于Configuration做的2条不同情况下的流程分析图:


配置类代码的实现应该说是短小和精炼,以后开发大型系统的时候完全可以借鉴此类似的原理。

<script type="text/java script">
<script type="text/java script">BAIDU_CLB_fillSlot("771048");
点击复制链接 与好友分享! 回本站首页
<script> function copyToClipBoard(){ var clipBoardContent=document.title + '\r\n' + document.location; clipBoardContent+='\r\n'; window.clipboardData.setData("Text",clipBoardContent); alert("恭喜您!复制成功"); }
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
您对本文章有什么意见或着疑问吗?请到 论坛讨论您的关注和建议是我们前行的参考和动力??
上一篇: C++ Primer Plus第6版18个重点笔记
下一篇: C++ 实用泛型编程之 虚拟函数(C++ virtual function)杂谈
相关文章
<script type="text/java script">BAIDU_CLB_fillSlot("182716");
<script type="text/java script">BAIDU_CLB_fillSlot("517916");
图文推荐