第一步加载类路径: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 alertersallAlerters.put("email", mailAlerter);// load all plugin alertersfinal 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.propertiesfinal 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实现(一)相关推荐

  1. Spring-bean的循环依赖以及解决方式___Spring源码初探--Bean的初始化-循环依赖的解决

    本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可以应用在我们实际开发项目中. 什么是循环依赖? 怎么检测循环依赖 Spring怎么解决循环依赖 S ...

  2. python处理回显_Python中getpass模块无回显输入源码解析

    本文主要讨论了python中getpass模块的相关内容,具体如下. getpass模块 昨天跟学弟吹牛b安利Python标准库官方文档的时候偶然发现了这个模块.仔细一看内容挺少的,只有两个主要api ...

  3. matlab的数值计算方法,数值计算方法中的一些常用算法的Matlab源码

    数值计算方法中的一些常用算法的Matlab源码,这些程序都是原创,传上来仅供大家参考,不足之处请大家指正,切勿做其它用途-- 说明:这些程序都是脚本函数,不可直接运行,需要创建函数m文件,保存时文件名 ...

  4. spark源码解读3之RDD中top源码解读

    更多代码请见:https://github.com/xubo245/SparkLearning spark源码解读系列环境:spark-2.0.1 (20161103github下载版) 1.理解 输 ...

  5. Fabric中PBFT源码解读 (3)

    文章目录 5. Preprepare消息的接收以及Prepare消息的发送 6. Prepare消息的接收以及Commit消息的发送 5. Preprepare消息的接收以及Prepare消息的发送 ...

  6. Golang 中 Slice的分析与使用(含源码)

    文章目录 1.slice结构体 2.slice初始化 3.append操作 4.slice截取 5.slice深拷贝 6.值传递还是引用传递 参考文献 众所周知,在golang中,slice(切片)是 ...

  7. Redis在Java中的使用及连接数据库(附源码)

    Redis在Java中的使用及连接数据库(附源码) 引言: 本文主要分享了Redis如何在IDEA中部署,运行:模拟加入Redis的操作: 文章目录 Redis在Java中的使用及连接数据库(附源码) ...

  8. python删除链表中重复的节点_Java编程删除链表中重复的节点问题解决思路及源码分享...

    一. 题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 二. 例子 输入链表:1->2->3->3->4->4-&g ...

  9. chrome浏览器开发者工具F12中某网站的sources下的源码如何批量保存?

    目录 chrome浏览器 开发者工具F12中某网站的sources下的源码如何批量保存 1. 常用保存Sources源码的两种方法 1.1单个文件 1.2 单个页面 2. 问题 3.解决方案 chro ...

最新文章

  1. 美国人到底为什么不待见人脸识别技术?
  2. RS485,RS232,USB,Ethernet 传输速度分别是多少
  3. 工具坐标6点法_轻松学机器人系列之各坐标系关系
  4. 螺旋遍历_螺旋形式的水平阶遍历
  5. linux 命令 语法,linux常用命令及语法
  6. Rust+Yew之hello world
  7. DNS 基础知识及 Linux DNS 服务器操作知识
  8. Git 小问题:fatal: not a git repository (or any of the parent directories): .git
  9. c语言链表移动北理工,北京理工大学c语言网络教室 链表
  10. Android小说阅读器案例
  11. 基于Flask框架实现Mock Server
  12. Java项目《谷粒商城》高级篇 个人错误总结
  13. HBase 过滤器使用
  14. nyoj54小明的存钱计划
  15. 计算模拟I2C的传输速率
  16. vb wps 链接单元格_使用VB快速制作WPS的COM加载项
  17. go之官方依赖管理工具dep安装和使用
  18. 【MySQL】浅谈MySQL中索引的基本操作以及背后的数据结构
  19. Java使用iText PDF合并PDF(将多个PDF合并成一个PDF)
  20. 王者荣耀服务器什么时候增加人数,王者荣耀2020年健康系统新规则 王者荣耀未成年一天能玩几小时...

热门文章

  1. 信息系统项目时间管理案例之关键路径案例
  2. JS_全球国家json数据,中文名+英文名
  3. WIN7硬盘安装Ubuntu18.04双系统(免U盘)
  4. python3通过qq邮箱发送邮件以及附件
  5. ig夺冠后服务器不稳定,LOL官方为iG夺冠庆典活动道歉:服务器不稳致奖励延迟...
  6. 吉大19秋学期计算机应用基础在线作业,吉大11春学期《计算机应用基础》在线作业二答案...
  7. 海康、大华IpCamera摄像机 RTSP地址和格式
  8. Linux平台下Java调用C函数
  9. 043_《Delphi程序开发范例宝典(第2版)》
  10. 快速掌握正则表达式,掌握常用的就ok