Modules里面有一个方法处理预处理组件:
/** * 处理预处理组件 * @param modules */ public static void processModules(Iterable<Module> modules) { for (Module module : modules) { if (module instanceof PreProcessModule) { for (Module module1 : modules) { ((PreProcessModule) module).processModule(module1); } } } }
插件调用的层次为:Modules->PluginsModule->PluginsService->XXPlugin;都是调用void processModule(Module module)方法。
区别在于
1:PluginsModule实现的是PreProcessModule接口。
2:PluginsService是自己本来的方法。
3:XXPlugin实现的是Plugin接口。
虽然他们都有processModule方法,但不是实现的同一个类。
接下来我们可以看一下插件服务具体实现的类PluginsService,具体做了什么?
查看代码:
/** * Constructs a new PluginService * @param settings The settings of the system * @param environment The environment of the system */ public PluginsService(Settings settings, Environment environment) { super(settings); this.environment = environment; this.checkLucene = componentSettings.getAsBoolean("check_lucene", true); this.esPluginPropertiesFile = componentSettings.get(ES_PLUGIN_PROPERTIES_FILE_KEY, ES_PLUGIN_PROPERTIES); this.loadClasspathPlugins = componentSettings.getAsBoolean(LOAD_PLUGIN_FROM_CLASSPATH, true); ImmutableList.Builder<Tuple<PluginInfo, Plugin>> tupleBuilder = ImmutableList.builder(); // first we load all the default plugins from the settings String[] defaultPluginsClasses = settings.getAsArray("plugin.types"); for (String pluginClass : defaultPluginsClasses) { Plugin plugin = loadPlugin(pluginClass, settings); PluginInfo pluginInfo = new PluginInfo(plugin.name(), plugin.description(), hasSite(plugin.name()), true, PluginInfo.VERSION_NOT_AVAILABLE); if (logger.isTraceEnabled()) { logger.trace("plugin loaded from settings [{}]", pluginInfo); } tupleBuilder.add(new Tuple<>(pluginInfo, plugin)); } // now, find all the ones that are in the classpath loadPluginsIntoClassLoader(); if (loadClasspathPlugins) { tupleBuilder.addAll(loadPluginsFromClasspath(settings)); } this.plugins = tupleBuilder.build(); // We need to build a List of jvm and site plugins for checking mandatory plugins Map<String, Plugin> jvmPlugins = Maps.newHashMap(); List<String> sitePlugins = Lists.newArrayList(); for (Tuple<PluginInfo, Plugin> tuple : this.plugins) { jvmPlugins.put(tuple.v2().name(), tuple.v2()); if (tuple.v1().isSite()) { sitePlugins.add(tuple.v1().getName()); } } // we load site plugins ImmutableList<Tuple<PluginInfo, Plugin>> tuples = loadSitePlugins(); for (Tuple<PluginInfo, Plugin> tuple : tuples) { sitePlugins.add(tuple.v1().getName()); } // Checking expected plugins String[] mandatoryPlugins = settings.getAsArray("plugin.mandatory", null); if (mandatoryPlugins != null) { Set<String> missingPlugins = Sets.newHashSet(); for (String mandatoryPlugin : mandatoryPlugins) { if (!jvmPlugins.containsKey(mandatoryPlugin) && !sitePlugins.contains(mandatoryPlugin) && !missingPlugins.contains(mandatoryPlugin)) { missingPlugins.add(mandatoryPlugin); } } if (!missingPlugins.isEmpty()) { throw new ElasticsearchException("Missing mandatory plugins [" + Strings.collectionToDelimitedString(missingPlugins, ", ") + "]"); } } logger.info("loaded {}, sites {}", jvmPlugins.keySet(), sitePlugins); MapBuilder<Plugin, List<OnModuleReference>> onModuleReferences = MapBuilder.newMapBuilder(); for (Plugin plugin : jvmPlugins.values()) { List<OnModuleReference> list = Lists.newArrayList(); for (Method method : plugin.getClass().getDeclaredMethods()) { if (!method.getName().equals("onModule")) { continue; } if (method.getParameterTypes().length == 0 || method.getParameterTypes().length > 1) { logger.warn("Plugin: {} implementing onModule with no parameters or more than one parameter", plugin.name()); continue; } Class moduleClass = method.getParameterTypes()[0]; if (!Module.class.isAssignableFrom(moduleClass)) { logger.warn("Plugin: {} implementing onModule by the type is not of Module type {}", plugin.name(), moduleClass); continue; } method.setAccessible(true); list.add(new OnModuleReference(moduleClass, method)); } if (!list.isEmpty()) { onModuleReferences.put(plugin, list); } } this.onModuleReferences = onModuleReferences.immutableMap(); this.refreshInterval = componentSettings.getAsTime("info_refresh_interval", TimeValue.timeValueSeconds(10)); }
可以看出其功能是注册ES根目录/[plugins]文件夹下的所有插件。