从plugin路径中读取依赖并构造对象——Azkaban源码解读之Alert plugin实现(一)
2021/6/21 17:56:10
本文主要是介绍从plugin路径中读取依赖并构造对象——Azkaban源码解读之Alert plugin实现(一),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
第一步加载类路径:azkaban.executor.AlerterHolder
allAlerters 是一个HashMap ,key为String
,value为Alerter
mailAlerter是系统内置的,无需处理,这里要加载的是自定义的插件告警
这里边读取配置信息里的alerter.plugin.dir
作为pluginDir,也就是插件文件夹
然后调用了方法loadPluginAlerters(pluginDir)
private Map<String, Alerter> loadAlerters(final Props props, final Emailer mailAlerter) { final Map<String, Alerter> allAlerters = new HashMap<>(); // load built-in alerters allAlerters.put("email", mailAlerter); // load all plugin alerters final String pluginDir = props.getString("alerter.plugin.dir", "plugins/alerter"); allAlerters.putAll(loadPluginAlerters(pluginDir)); return allAlerters; }
第二步我们追踪loadPluginAlerters(pluginDir)
这里边有一个方法需要注意:
- Class<?> alerterClass =
PluginUtils.getPluginClass(pluginClass, pluginDir, extLibClassPaths, parentLoader);
这个方法我们将在第二部分解析。
private Map<String, Alerter> loadPluginAlerters(final String pluginPath) { final File alerterPluginPath = new File(pluginPath); //如果文件不存在 直接返回一个空集合 if (!alerterPluginPath.exists()) { return Collections.<String, Alerter>emptyMap(); } final Map<String, Alerter> installedAlerterPlugins = new HashMap<>(); //获取父类加载器 final ClassLoader parentLoader = getClass().getClassLoader(); //获取插件目录下的所有文件 final File[] pluginDirs = alerterPluginPath.listFiles(); final ArrayList<String> jarPaths = new ArrayList<>(); //遍历所有插件目录下的所有文件 for (final File pluginDir : pluginDirs) { // load plugin properties // 读取配置文件pluginDir下的自定义alert文件夹中的con目录下的plugin.properties final Props pluginProps = PropsUtils.loadPluginProps(pluginDir); if (pluginProps == null) { continue; } //如果获取到配置文件,则读取如下三个配置信息 final String pluginName = pluginProps.getString("alerter.name"); final List<String> extLibClassPaths = pluginProps.getStringList("alerter.external.classpaths", (List<String>) null); final String pluginClass = pluginProps.getString("alerter.class"); //alerter.class是必须要配置的 if (pluginClass == null) { logger.error("Alerter class is not set."); continue; } else { logger.info("Plugin class " + pluginClass); } //加载所有的plugin类 Class<?> alerterClass = PluginUtils.getPluginClass(pluginClass, pluginDir, extLibClassPaths, parentLoader); if (alerterClass == null) { continue; } //获取类的.class路径 final String source = FileIOUtils.getSourcePathFromClass(alerterClass); logger.info("Source jar " + source); jarPaths.add("jar:file:" + source); Constructor<?> constructor = null; try { constructor = alerterClass.getConstructor(Props.class); } catch (final NoSuchMethodException e) { logger.error("Constructor not found in " + pluginClass); continue; } //反射方法获取插件对象 Object obj = null; try { obj = constructor.newInstance(pluginProps); } catch (final Exception e) { logger.error(e); } if (!(obj instanceof Alerter)) { logger.error("The object is not an Alerter"); continue; } final Alerter plugin = (Alerter) obj; installedAlerterPlugins.put(pluginName, plugin); } //将所有插件类型以及所属对象放入Map中返回 return installedAlerterPlugins; }
/** * Get URLClassLoader */ public static URLClassLoader getURLClassLoader(final File pluginDir, List<String> extLibClassPaths, ClassLoader parentLoader) { final File libDir = new File(pluginDir, LIBRARY_FOLDER_NAME); if (libDir.exists() && libDir.isDirectory()) { final File[] files = libDir.listFiles(); final ArrayList<URL> urls = getUrls(files); if (extLibClassPaths != null) { for (final String extLibClassPath : extLibClassPaths) { try { final File extLibFile = new File(pluginDir, extLibClassPath); if (extLibFile.exists()) { if (extLibFile.isDirectory()) { // extLibFile is a directory; load all the files in the // directory. final File[] extLibFiles = extLibFile.listFiles(); urls.addAll(getUrls(extLibFiles)); } else { final URL url = extLibFile.toURI().toURL(); urls.add(url); } } else { logger.error( "External library path not found. path = " + extLibFile.getAbsolutePath() ); continue; } } catch (final MalformedURLException e) { logger.error( "Invalid External library path. path = " + extLibClassPath + " dir = " + pluginDir, e ); } } } return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentLoader); } else { logger.error("Library path not found. path = " + libDir); return null; } }
这篇关于从plugin路径中读取依赖并构造对象——Azkaban源码解读之Alert plugin实现(一)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)
- 2024-05-30【Java】百万数据excel导出功能如何实现
- 2024-05-30我们小公司,哪像华为一样,用得上IPD(集成产品开发)?