zoukankan      html  css  js  c++  java
  • Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2)

    ——进入main函数打印包信息

    找到了main函数,也建立了快速启动的方法,然后我们就进去看一看。

    进入NameNode和DataNode的主函数后,发现形式差不多:

    1. public static void main(String args[]) {
    2.     try {
    3.       StringUtils.startupShutdownMessage(DataNode.class, args, LOG);
    4.       DataNode datanode = createDataNode(args, null); //NameNode中类型换成NameNode
    5.       if (datanode != null)
    6.         datanode.join();
    7.     } catch (Throwable e) {
    8.       LOG.error(StringUtils.stringifyException(e));
    9.       System.exit(-1);
    10.     }
    11.   }

    进来后第一句是什么,当我们运行到这里时发现:

    我们在运行每一个程序时,头上都会在控制台或日志文件中输出这一段话。信息内容主要是描述启动了哪个类,主机,参数,版本,以及编译信息。

    跟踪进入StringUtils.startupShutdownMessage类中,

    1. public static void startupShutdownMessage(Class<?> clazz, String[] args,
    2.                                      final org.apache.commons.logging.Log LOG) {
    3.     final String hostname = getHostname();
    4.     final String classname = clazz.getSimpleName();
    5.     LOG.info(
    6.         toStartupShutdownString("STARTUP_MSG: ", new String[] {
    7.             "Starting " + classname,
    8.             " host = " + hostname,
    9.             " args = " + Arrays.asList(args),
    10.             " version = " + VersionInfo.getVersion(),
    11.             " build = " + VersionInfo.getUrl() + " -r "
    12.                          + VersionInfo.getRevision()
    13.                          + "; compiled by '" + VersionInfo.getUser()
    14.                          + "' on " + VersionInfo.getDate()}
    15.         )
    16.       );
    17.  
    18.     Runtime.getRuntime().addShutdownHook(new Thread() {
    19.       public void run() {
    20.         LOG.info(toStartupShutdownString("SHUTDOWN_MSG: ", new String[]{
    21.           "Shutting down " + classname + " at " + hostname}));
    22.       }
    23.     });
    24.   }

    在第5行,通过log4j组件进行了输出(这里log4j是一个日志写入组件,对就.net中是log4net,详细就不描述了)。然后前几项类名(className)、主机(hostname)、参数(args)没什么问题,通过应函数取得即可。

    其他信息稍后,先看一下第18行,这里是在进程上加了一个勾子,来捕获关闭事件,然后在关闭时,可以输出一下信息,我们可以试下,在控制台运行时,然后按下Ctrl+C终止时,可以看到以下信息:

    这段信息,正是第20行代码进行输出的。

     

    其它信息如版本和编译信息呢? 输入内容中是比较细的,它是如何知道的呢? 跟进去看:

    1.   private static HadoopVersionAnnotation version;
    2. static {
    3.     myPackage = HadoopVersionAnnotation.class.getPackage();
    4.     version = myPackage.getAnnotation(HadoopVersionAnnotation.class);
    5.   }
    6.  public static String getUser() {
    7.     return version != null ? version.user() : "Unknown";
    8.   }

    这段代码发现getuser是通过一个HadoopVersionAnnotation类的user()函数,而这个HadoopVersionAnnotation发现是一个接口:

    1. @Retention(RetentionPolicy.RUNTIME)
    2. @Target(ElementType.PACKAGE)
    3. public @interface HadoopVersionAnnotation {...}

    这个接口是一个比较特殊的接口,在1 2 行可以看到有一特殊标记。我们知道,在java中有些函数上是可以加一个特殊标记的,如@override。而这个override就是一个特殊的标记,它也是一个接口,可以附加在这个函数上,让其具有特殊意义。

    而我们的这个HadoopVersionAnnotation就是这样的一个接口,并且它附加在Package上,即用于获取包的信息。

    附件在包上的话,这又是在哪呢? 我们在build文件夹找到了:

    发现,这里有一个java文件,然后里面定义了包,在包上加了一个@信息,这正是这个接口的定义,同时,在这里传入了版本,编译者,编译时间等信息。于是我们在程序里就可以获取到这里的值了。

    但又在想了,这个build文件夹不是一开始没有的么,在运行ant后才创建的么,这个java文件是哪来的?

    我们发现,在src文件夹下有saveVersion.sh这么一个文件:

    基本可以看出,正是往package-info.java中写入相关信息。

    而这个saveVersion.sh可以再追查,在build.xml中有调用。

    这个@XXX 其实就是.net中的Attribute称之为特性(属性的属性)。

     

    好的,这个main函数中的第一个砍就算过了。

     

     

  • 相关阅读:
    SpringMVC-------1.spriingMVC简介和简单案例
    MyBatis-----7.pageHelper分页助手
    MyBatis-----4.实现关联表查询
    MyBatis-----6.逆向工程(generator)
    MyBatis-----1.MyBatis简介和使用
    MyBatis-----2.通过映射接口实现CRUD
    Spring-2
    Spring-1
    php调用阿里云手机归属地查询
    php身份证验证
  • 原文地址:https://www.cnblogs.com/zjfstudio/p/4064169.html
Copyright © 2011-2022 走看看