[关闭]
@aloxc 2017-12-05T06:24:53.000000Z 字数 3649 阅读 514

我们一起学ignite之插件

一起学 ignite 源码分析 插件


ignite中支持我们自己定义插件【代码中已经预留了坑,但是还没拉屎,至少没拉完】,我们可以从代码中看到关于插件的一些处理流程,
1.IgniteKernal类中有下面的代码,

  1. //本行代码是通过ServiceLoad来读取资源文件META/services/org.apache.ignite.plugin.PluginProvider中定义的插件类表,这个资源文件中的每行就是一个实现了接口PluginProvider的一个类
  2. List<PluginProvider> plugins = IgniteUtils.allPluginProviders();
  3. ....
  4. //初始化ignite服务上下文,最终里面的调用MarshallerContextAdapter类的构造方法代码,见下面2中再说,
  5. ctx = new GridKernalContextImpl(log,
  6. this,
  7. cfg,
  8. gw,
  9. utilityCachePool,
  10. marshCachePool,
  11. execSvc,
  12. sysExecSvc,
  13. p2pExecSvc,
  14. mgmtExecSvc,
  15. callbackExecSvc,
  16. plugins);
  17. ...
  18. //开始一个处理器来处理插件,具体分析见3中再说
  19. startProcessor(new IgnitePluginProcessor(ctx, cfg, plugins));

2.上面说的IgniteKernal中调用类GridKernalContextImpl类的构造方法,而GridKernalContextImpl类的构造方法又实例化一个MarshallerContextImpl,MarshallerContextImpl调用父类MarshallerContextAdapter中的构造方法

  1. public MarshallerContextAdapter(@Nullable List<PluginProvider> plugins) {
  2. System.out.println("准备注册插件处理器,插件数量 = " + plugins.size());
  3. try {
  4. ClassLoader ldr = IgniteUtils.gridClassLoader();
  5. Enumeration<URL> urls = ldr.getResources(CLS_NAMES_FILE);
  6. boolean foundClsNames = false;
  7. while (urls.hasMoreElements()) {
  8. processResource(urls.nextElement());
  9. foundClsNames = true;
  10. }
  11. if (!foundClsNames)
  12. throw new IgniteException("从文件中加载类异常" +
  13. "[file=" + CLS_NAMES_FILE + ", ldr=" + ldr + ']');
  14. URL jdkClsNames = ldr.getResource(JDK_CLS_NAMES_FILE);
  15. if (jdkClsNames == null)
  16. throw new IgniteException("从文件中加载类异常" +
  17. "[file=" + JDK_CLS_NAMES_FILE + ", ldr=" + ldr + ']');
  18. processResource(jdkClsNames);
  19. checkHasClassName(GridDhtPartitionFullMap.class.getName(), ldr, CLS_NAMES_FILE);
  20. checkHasClassName(GridDhtPartitionMap2.class.getName(), ldr, CLS_NAMES_FILE);
  21. checkHasClassName(HashMap.class.getName(), ldr, JDK_CLS_NAMES_FILE);
  22. if (plugins != null && !plugins.isEmpty()) {
  23. for (PluginProvider plugin : plugins) {
  24. final String clazzProp = "META-INF/" + plugin.name().toLowerCase() + ".classnames.properties";
  25. URL pluginClsNames = ldr.getResource(clazzProp);
  26. if (pluginClsNames != null){
  27. processResource(pluginClsNames);
  28. }else{
  29. System.out.println("代码中有定义了插件" + plugin.getClass().getName() + ",但是没有对应的资源属性文件\t" + clazzProp);
  30. }
  31. }
  32. }else{
  33. System.out.println("插件为空");
  34. }
  35. }
  36. catch (IOException e) {
  37. throw new IllegalStateException("初始化调度上下文失败.", e);
  38. }
  39. }

3、startProcessor(new IgnitePluginProcessor(ctx, cfg, plugins));
先说创建实例IgnitePluginProcessor的代码,

  1. public IgnitePluginProcessor(GridKernalContext ctx, IgniteConfiguration cfg, List<PluginProvider> providers) {
  2. super(ctx);
  3. ExtensionRegistryImpl registry = new ExtensionRegistryImpl();
  4. for (PluginProvider provider : providers) {
  5. GridPluginContext pluginCtx = new GridPluginContext(ctx, cfg);
  6. if (GridFunc.isEmpty(provider.name()))
  7. throw new IgniteException("插件名称不能为空");
  8. if (plugins.containsKey(provider.name()))
  9. throw new IgniteException("插件名称重复: " + provider.name());
  10. plugins.put(provider.name(), provider);
  11. pluginCtxMap.put(provider, pluginCtx);
  12. provider.initExtensions(pluginCtx, registry);
  13. if (provider.plugin() == null)
  14. throw new IgniteException("插件中未定义插件类,也就是" + provider.getClass() + "类中的方法plugin()未返回有效的插件");
  15. }
  16. extensions = registry.createExtensionMap();
  17. }
  1. private void startProcessor(GridProcessor proc) throws IgniteCheckedException {
  2. ctx.add(proc);
  3. try {
  4. if (!skipDaemon(proc))
  5. proc.start();
  6. }
  7. catch (IgniteCheckedException e) {
  8. throw new IgniteCheckedException("Failed to start processor: " + proc, e);
  9. }
  10. }

本方法中,先判断下处理器是否是非守护方式运行(判断),如果不是非守护方式运行就调用当前处理器的start方法。我们现在分析的是插件处理器,那么就是执行IgnitePluginProcessor中的start方法,start中就只调用了askPluginsInfo()输出下插件信息,

  1. private void ackPluginsInfo() {
  2. if (plugins.isEmpty()) {
  3. IgniteUtils.warn(log, " ^-- 插件为空");
  4. }
  5. else {
  6. IgniteUtils.quietAndInfo(log, "配置插件列表:");
  7. for (PluginProvider plugin : plugins.values()) {
  8. IgniteUtils.quietAndInfo(log, " ^-- " + plugin.name() + " " + plugin.version());
  9. IgniteUtils.quietAndInfo(log, " ^-- " + plugin.copyright());
  10. IgniteUtils.quietAndInfo(log, "");
  11. }
  12. }
  13. }

通篇就只有一个调用插件初始化的方法代码provider.initExtensions(pluginCtx, registry);这个方法在我们实现的插件类而已,貌似功能不强,所以插件充其量就是半拉子工程

x

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注