從plugin路徑中讀取依賴並構造對象——Azkaban源碼解讀之Alert plugin實現(一)

香山上的麻雀 2022-01-07 16:44:03 阅读数:508

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;
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

第二步我們追踪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;
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
 /** * 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;
}
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
版权声明:本文为[香山上的麻雀]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201071644026112.html