交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
第8 章:Configuration
分享
未结
0
548
李延
LV6
2022-03-13
悬赏:20积分
# 1. 使用 Configuration 是hadoop用于加载配置文件的类,我们平常配置xml变量,都是在Configuration中进行加载的。我们先看一个简单的用例: ![](//cdn.hiboot.cn/f8c99189ce7a4756abcbbc9b43e7a1f2.png) 在我们项目的文件下添加core-site.xml 文件。并配置fs.defaulFS变量。解析看代码 ```java @Test public void defaultFS() { Configuration configuration = new Configuration(); final String defaultFS = configuration.get("fs.defaultFS"); System.out.println(defaultFS); } ``` 我们看到直接创建Configuration 对象就可以读取到core-site.xml 中的变量 ## 1.1 同名变量处理 ![](//cdn.hiboot.cn/4f92421aadc64120963bfd924001d354.png) 我们知道hadoop文件有core-default和core-site 两种配置文件,但当文件出现重名变量时,我们可以设置final来指定使用哪个变量 ## 1.2 自定义文件价值 除了默认的文件外,我们还可以指定自定义路径的文件 ```java @Test public void addResource() { Configuration configuration = new Configuration(); //加载jar包内的文件 configuration.addResource("test.xml"); //Path内为文件的全路径 configuration.addResource(new Path("c:\\test.xml")); final String defaultFS = configuration.get("fs.defaultFS"); System.out.println(defaultFS); } ``` 我们可以调用addResource 来加载文件 # 2. 源码解析 ## 2.1 成员变量 ```java //默认加载的文件路径,比如上面实例中默认会加载core相关的文件 private static final CopyOnWriteArrayList<String> defaultResources = new CopyOnWriteArrayList<String>(); //用户自定义加载的文件,通过addResource 添加 private ArrayList<Resource> resources = new ArrayList<Resource>(); //废弃字段的转换,当我们使用废弃字段时,会自动转换为新的字段值,里面其实就是一个map,key为废弃的字段,value就是对应新的字段,值时数组格式 private static AtomicReference<DeprecationContext> deprecationContext = new AtomicReference<DeprecationContext>( new DeprecationContext(null, defaultDeprecations)); //保存解析后的字段 private Properties properties; ``` ## 2.2 初始化 ```java static { // Add default resources //向defaultResources 中添加core-default.xml 与core-site.xml 配置文件 addDefaultResource("core-default.xml"); addDefaultResource("core-site.xml"); // print deprecation warning if hadoop-site.xml is found in classpath //如果有hadoop-site.xml配置文件也会添加,但会有告警推荐在core相关配置中配置 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("hadoop-site.xml"); } } ``` 我们看到系统默认读取了core-default.xml 、core-site.xml、hadoop-site.xml 的配置。 ## 2.3 get方法 ```java public String get(String name) { //如果字段已经废弃,获取新字段名称 String[] names = handleDeprecation(deprecationContext.get(), name); String result = null; for(String n : names) { //获取字段,通过getProps() 获取到字段,通过substituteVars 解析字段 result = substituteVars(getProps().getProperty(n)); } return result; } ``` 我们继续看getProps ```java protected synchronized Properties getProps() { //当第一次时,会调用loadProps 加载字段 if (properties == null) { properties = new Properties(); loadProps(properties, 0, true); } return properties; } ``` ```java private synchronized void loadProps(final Properties props, final int startIdx, final boolean fullReload) { if (props != null) { Map<String, String[]> backup = updatingResource != null ? new ConcurrentHashMap<>(updatingResource) : null; //这里resources 就是我们自己添加的配置文件 loadResources(props, resources, startIdx, fullReload, quietmode); if (overlay != null) { props.putAll(overlay); if (backup != null) { for (Map.Entry<Object, Object> item : overlay.entrySet()) { String key = (String) item.getKey(); String[] source = backup.get(key); if (source != null) { updatingResource.put(key, source); } } } } } ``` ```java private void loadResources(Properties properties, ArrayList<Resource> resources, int startIdx, boolean fullReload, boolean quiet) { //首先读取默认的配置文件 if(loadDefaults && fullReload) { for (String resource : defaultResources) { loadResource(properties, new Resource(resource, false), quiet); } } //之后再添加我们自己的配置文件 for (int i = startIdx; i < resources.size(); i++) { Resource ret = loadResource(properties, resources.get(i), quiet); if (ret != null) { resources.set(i, ret); } } this.addTags(properties); } ``` 后面就是对xml文件的 读取,不再深入解析。 # 3 子类说明 在Configuration 中只是默认加载了core的配置,当我们使用hadoop不同的组件时,会加载各自的组件。比如hdfs中 ## 3.1 HdfsConfiguration HdfsConfiguration继承自Configuration,只是扩展了默认加载文件相关内容如下: ```java static { addDeprecatedKeys(); // adds the default resources Configuration.addDefaultResource("hdfs-default.xml"); Configuration.addDefaultResource("hdfs-rbf-default.xml"); Configuration.addDefaultResource("hdfs-site.xml"); Configuration.addDefaultResource("hdfs-rbf-site.xml"); } ``` 我们看到它默认加载了所有hdfs相关的配置。 ## 3.2 defaultResources 说明 我们回头看看Configuration里的defaultResources,他作用是保存我们默认需要加载哪些文件,但他是static的。也就是说,我们如果同时使用了HdfsConfiguration和Configuration,其实Configuration 也会加载hdfs相关的配置,测试代码如下: ```java @Test public void hdfs() { Configuration configuration = new Configuration(); Configuration hdfsConfiguration = new HdfsConfiguration(); final String defaultFS = configuration.get("fs.defaultFS"); System.out.println(defaultFS); } ``` ![](//cdn.hiboot.cn/957ddfa16c704c73902897b0f26adbdc.png) debug 我们发现Configuration 同时也加载了hdfs的所有文件
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号