關于ToolRunner,先看nutch的代碼:
public static void main(String args[]) throws Exception {
Configuration conf = NutchConfiguration.create();
int res = ToolRunner.run(conf, new Crawl(), args);
System.exit(res);
}
ToolRunner其實是整個nutch的入口,要想弄明白先來看看下面的東西(是Hadoop裡的東西):
Configurable接口:
public interface Configurable {
void setConf(Configuration conf);
Configuration getConf();
}
這個接口隻有兩個方法setConf和getConf;
Configured實作了Configurable接口:
public class Configured implements Configurable {
private Configuration conf;
public Configured() {
this(null);
}
public Configured(Configuration conf) {
setConf(conf);
}
public void setConf(Configuration conf) {
this.conf = conf;
}
public Configuration getConf() {
return conf;
}
}
接下來我們的主角Tool出現了,它作為接口繼承了Configurable接口,隻有run()方法:
public interface Tool extends Configurable {
int run(String [] args) throws Exception;
}
再來看一下Toolrunner:
public class ToolRunner {
public static int run(Configuration conf, Tool tool, String[] args)
throws Exception{
if(conf == null) {
conf = new Configuration();
}
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
//set the configuration back, so that Tool can configure itself
tool.setConf(conf);
//get the args w/o generic hadoop args
String[] toolArgs = parser.getRemainingArgs();
return tool.run(toolArgs); //注意這一行
}
}
ToolRunner 在最後調用了Tool的run()方法;
看完這個我們再來看看nutch的源碼你就明白了:
public class Crawl extends Configured implements Tool
這個是Crawl的定義,它繼承了Configured并作為Tool的接口:
在看main方法中的這句:
int res = ToolRunner.run(conf, new Crawl(), args);
再看上面ToolRunner的定義,你會發現ToolRunner的GenericOptionsParser方法會先處理hadoop的指令,在把剩下的指令交給tooArgs儲存,後傳遞給tool的run方法,在nutch這裡,Crawl是Tool接口的實作,new Crawl()之後,ToolRunner最終會把剩下的指令交給Crawl自己的run()方法,最終nutch會從這個run方法開始:
。。。。。
}