您的位置:首页 > 其它

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

2012-04-14 19:19 651 查看
分类: Nutch2011-09-15
00:00 590人阅读 评论(0) 收藏 举报

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

----------------------------------------

在Nutch中,大量的可扩展的部分都使用了插件来做,如网页下载时所用的协议选择,解析不同类型的网页,url的过滤和规范化都使用了Nutch的插件机制。

Nutch中插件的主要目标是:

可扩展性:用户可以通过实现相应的接口来生成自己的扩展插件
灵活性:任务人都可以参与插件的编写。
可维护性:插件的开发者只要实现相应的扩展接口,而不需要关注插件的内部原理。

下面对其原理和代码做一个简单的分析。


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运行插件

本机运行出现的帮助

[html] view
plaincopy

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协议的命令:

[html] view
plaincopy

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命令就是调用这个函数的

[html] view
plaincopy

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: