Nutch插件加載分析

   當某個插件需要被加載時, 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);
        }
 
 
<?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以供參考。

轉自 http://www.blogjava.net/redmu/archive/2006/12/02/85092.html
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章