当某个插件需要被加载时,
				Nutch
				会加载所有插件的相关接口到缓存,此后每个插件需要实例的时候,根据相关接口和相关接口实现实例在缓存内的记录,使用反射实现一个实例并返回,下面以
				QueryFilter
				的所有插件被加载例子进行说明。
		
		
				
						
						 
				
		
		
				具体代码参看org.apache.nutch.seacher.QueryFilters<init>
(
				1
				)当第一次需要得到
				QueryFilter
				的一个子类的实例时,使用下面这句话试图获得所有的实例:
		
		
				
						 
				
		
		
				
						this.queryFilters = 
				
		
		
				
						(QueryFilter[]) conf.getObject(QueryFilter.class .getName());
				
		
		
				
						 
				
		
		
				(2)如果为空,则试图从插件仓库中得到该插件的扩展点:
		
		
				
						 
				
		
		
				
						ExtensionPoint point = PluginRepository.get(conf)
				
		
		
				
						
								            .getExtensionPoint(QueryFilter.X_POINT_ID);
				
		
		
				
						 
				
		
		
				在
				
						PluginRepository.get(conf)
				
				这句话中,返回插件仓库,如果仓库为空,会初始化所有插件:
		
		
				
						 
				
		
		
				
						
								| 
										 
												
														初始化所有插件PluginRepository.<init>
												
										 
								 | 
						
						
								| 
										 
												
														①     
												
												试图从缓存内获得插件仓库。
										 
										
												
														PluginRepository result = (PluginRepository)CACHE.get(conf);
												
										 
										
												
														②     
												
												如果未获得,则初始化所有插件
										 
										
												
														result = new PluginRepository(conf);
												
										 
										
												
														l         
												
												初始化以活动插件和扩展点的集合
										 
										
												
														fActivatedPlugins = new HashMap();
												
										 
										
												
														
																      fExtensionPoints = new HashMap();
												
										 
										
												
														
																      this.conf = conf;
												
										 
										
												
														l         
												
												获得插件存放位置
										 
										
												
														     
														
																 String[] pluginFolders = conf.getStrings("plugin.folders");
												
										 
										
												
														l         
												
												实例化PluginManifestParser:
										 
										
												
														  
														
																 PluginManifestParser manifestParser =  new PluginManifestParser(conf, this);
												
										 
										
												
														   PluginManifestParser
												是一个封装了PluginRepository的工具类,在构造时,分析每个插件的文件夹,把每个plugin.xml文件的内容进行分析,记录了所有的插件接口和插件接口内所包含的所有实现类的关系。
										 
										
												
														l         
												
												放入缓存
										 
										
												
														   
														CACHE.put(conf, result);
												
										 
										
												
														
																 
														
												
										 
										
												Plugin.xml
												描述内容见附录一
										 
								 | 
						
				
		
		
				
						 
				
		
		
				(3)获得所有QueryFilter的子类描述。
		
		
				
						Extension[] extensions = point.getExtensions();
				
		
		
				
						
								 
						
				
		
		
				(4)循环获得每个插件的两个参数,fieldName和rawFieldNames,生成每个filter插件实例。
		
		
				
						for (int i = 0; i < extensions.length; i++) {
				
		
		
				
						
								          Extension extension = extensions[i];
				
		
		
				
						
								          ArrayList fieldNames = parseFieldNames(extension, "fields");
				
		
		
				
						
								          ArrayList rawFieldNames = parseFieldNames(extension, "raw-fields");
				
		
		
				
						
								          if (fieldNames.size() == 0 && rawFieldNames.size() == 0) {
				
		
		
				
						
								            if (LOG.isWarnEnabled()) {
				
		
		
				
						
								              LOG.warn("QueryFilter: " + extension.getId()
				
		
		
				
						
								                     + " names no fields.");
				
		
		
				
						
								            }
				
		
		
				
						
								            continue;
				
		
		
				
						
								          }
				
		
		
				
						
								          filters[i] = (QueryFilter) extension.getExtensionInstance();
				
		
		
				
						
								          FIELD_NAMES.addAll(fieldNames);
				
		
		
				
						
								          FIELD_NAMES.addAll(rawFieldNames);
				
		
		
				
						
								          conf.setObject("FIELD_NAMES", FIELD_NAMES);
				
		
		
				
						
								          RAW_FIELD_NAMES.addAll(rawFieldNames);
				
		
		
				
						
								          conf.setObject("RAW_FIELD_NAMES", RAW_FIELD_NAMES);
				
		
		
				
						
								    
								    }
				
		
		
				
						 
至此,所有实现QueryFilter的子类实例均被加载。如果需要开发自己的插件,同样可以参考这个过程,plugin.xml的具体内容的描述负在下面:
				
		
		
				
						
						
				 
		
				<?xml version="1.0" encoding="UTF-8"?>
		
		
				
						 
				
		
		
				<!—
				插件的根元素,根元素的属性表明了一个插件的基本身份-->
		
		
				<plugin id=”
				唯一身份(被插件仓库作为身份标示)” name=”名称” version=”版本号” 
		
		
				provider=”
				作者”class=”类名(可选)”>
		
		
				
						 
				
		
		
				<!--
				以下两个内容中引用的类库,都是作为本类使用反射时生成实例所需要的类库-->
		
		
				<runtime>
		
		
				
						    <library name="
				运行时的类库">
		
		
				
						        
						 <!—
				如果存在此元素,则保存到fExportedLibs(输出类库集合),否则存放到
		
		
				fNotExportedLibs
				(非输出类库集合)-->
		
		
				
						         <export name="*"/>
		
		
				
						    </library>
		
		
				</runtime>
		
		
				
						 
				
		
		
				<requires>
		
		
				
						    <!—
				需要注意,此处所需要的类库,包括该类库所需的类库,都不得在此引用本插件-->
		
		
				
						    <import plugin="
				所需类库"/>
		
		
				</requires>
		
		
				
						 
				
		
		
				<extension id="
				本类的包名(从代码中看没有被使用)"
		
		
				
						              name="
				类名(从代码中看没有被使用)"
		
		
				
						              point="
				扩展点类名(即接口名)">
		
		
				
						      <implementation id="
				实现扩展的唯一标识(与类名相同,被parse-plugins.xml
		
		
				作为身份表示使用)"
		
		
				
						           class="
				实现扩展的类的类名"/>
		
		
				
						      <parameter name="
				参数名"  value="参数值"/>
		
		
				</extension>
		
		
				
						 
				
		
		
				<!—
				仅在nutch-extensionpoints\plugin.xml中存在,一次性加载纪录下所有的扩展点的名称-->
		
		
				<
				
				
				extension-point id=”
				扩展点唯一标识”name=”扩展点名”/>
		
		
				
						 
				
		
		
				</plugin>
下次会写一个完整的plugin以供参考。
转载请注明出处。