Nutch 1.3 学习笔记 10-1 - Ntuch 插件机制简单介绍

Nutch 1.3 学习笔记 10 -1 - Ntuch 插件机制简单介绍
----------------------------------------
  在Nutch中,大量的可扩展的部分都使用了插件来做,如网页下载时所用的协议选择,解析不同类型的网页,url的过滤和规范化都使用了Nutch的插件机制。
  Nutch中插件的主要目标是:
  1.   可扩展性:用户可以通过实现相应的接口来生成自己的扩展插件
  2.   灵活性:任务人都可以参与插件的编写。
  3.   可维护性:插件的开发者只要实现相应的扩展接口,而不需要关注插件的内部原理。
  下面对其原理和代码做一个简单的分析。

1. 一些概念

1.1 插件仓库(PluginRepository)

插件仓库是一个所有插件的注册器,在系统启动时,这个仓库是通过分析插件目录中所有插件的mainfest文件来生成。对于每一个插件都会生成一个插件描述实例,它包含了每一个插件的元数据,所以插件的真正的实例会在用的时候再来创建,也就是所谓的延迟插件载入机制(lazy plugin loading)。


1.2 插件(Plugin)

Nutch中的插件实际上是一系列自定义逻辑的容器,而这些自定义逻辑为Nutch的核心功能提供扩展和为其它插件提供扩展API。一个插件要提供一个或者一组扩展。而对于扩展点来说(ExtensionPoints)来说,这些扩展都可以被看做是一组可以被动态加载的监听器。每一个具体的插件都扩展自基类Plugin,而这些实例又被用于去管理相关功能的生命周期。插件打开与关闭都由Nutch的插件管理系统来操作。

1.3 扩展(Extension)

扩展相当于一种被安装在具体的扩展点(ExtensionPoint)上的监听描述符,这里的扩展点扮演了一个发布者的角色。


1.4 扩展点(ExtensionPoint)

扩展点提供了一类具体功能扩展的元信息,它包含了具体的扩展。

1.5 插件描述符(PluginDescriptor)

插件描述符提供了一种对于Nutch所插件元数据的一种描述,它包含了国际化资源和插件本自的classloader。而这些元数据包含了插件(Plugin)、插件扩展点(ExtensionPoint)和扩展(Extension).而这里为了能够通过插件描述符来管理元数据,提供了一种延迟加载机制。



2. 使用bin/nutch运行插件

   本机运行出现的帮助
   
lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ bin/nutch plugin 
	Usage: PluginRepository pluginId className [arg1 arg2 ...]

   这里主要有三个参数:
  •    pluginId:这个是插件的id号,它是每一个插件目录中的plugin.xml文件里里面plugin标签中的id属性
  •    className:这是扩展插件的类全
  •    args:这是插件main函数的参数


一个简单的调用protocoal的Http协议的命令:

bin/nutch plugin protocol-http org.apache.nutch.protocol.http.Http -verbose -timeout 10 http://www.baidu.com	

  •         pluginId: protocol-http
  • className: org.apache.nutch.protocol.http.Http
  • args: -verbos -timeout 10 http://www.baidu.com

这里的输出就是baidu的网页源代码。
下面简单分析一下其调用的源代码。


3. 源代码分析


这是PluginRepository.java中的main函数,上面的bin/nutch plugin命令就是调用这个函数的

	public static void main(String[] args) throws Exception {
    if (args.length < 2) {
      System.err
          .println("Usage: PluginRepository pluginId className [arg1 arg2 ...]");
      return;
    }
	// 生成Nutch的配置
	// 这里主要使用的参数是plugin的目录名,还有plugin.includes包含哪些要读取的plugin
    Configuration conf = NutchConfiguration.create();
	// 根据配置生成一个插件仓库,并且对其进行初始化
    PluginRepository repo = new PluginRepository(conf);
    // args[0] - plugin ID
	// 根据插件ID得到特定的插件描述符
    PluginDescriptor d = repo.getPluginDescriptor(args[0]);
    if (d == null) {
      System.err.println("Plugin '" + args[0] + "' not present or inactive.");
      return;
    }
	// 从插件描述符对象中得到类加载器
    ClassLoader cl = d.getClassLoader();
    // args[1] - class name
    Class clazz = null;
    try {
		// 加载对应的类
      clazz = Class.forName(args[1], true, cl);
    } catch (Exception e) {
      System.err.println("Could not load the class '" + args[1] + ": "
          + e.getMessage());
      return;
    }
    Method m = null;
    try {
		// 得到特定的main方法
      m = clazz.getMethod("main", new Class[] { args.getClass() });
    } catch (Exception e) {
      System.err.println("Could not find the 'main(String[])' method in class "
          + args[1] + ": " + e.getMessage());
      return;
    }
    String[] subargs = new String[args.length - 2];
    System.arraycopy(args, 2, subargs, 0, subargs.length);
	// 这里是运行插件的main方法
    m.invoke(null, new Object[] { subargs });
  }




4. 总结

   这里只是对Nutch的插件做一个简单的介绍,下面我们会来自己动手写一个相应的插件,最后我们会看一下其插件的实现原理。

5. 参考

http://wiki.apache.org/nutch/PluginCentral?highlight=%28%28WhichTechnicalConceptsAreBehindTheNutchPluginSystem%29%29
http://www.mikkoo.info/?p=101
http://hi.baidu.com/bupo_jung/blog/item/0603dcd871af2e2033fa1cd5.html

你可能感兴趣的:(exception,ClassLoader,String,扩展,extension,Ntuch)