从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 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实现(一)相关推荐
- Spring-bean的循环依赖以及解决方式___Spring源码初探--Bean的初始化-循环依赖的解决
本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可以应用在我们实际开发项目中. 什么是循环依赖? 怎么检测循环依赖 Spring怎么解决循环依赖 S ...
- python处理回显_Python中getpass模块无回显输入源码解析
本文主要讨论了python中getpass模块的相关内容,具体如下. getpass模块 昨天跟学弟吹牛b安利Python标准库官方文档的时候偶然发现了这个模块.仔细一看内容挺少的,只有两个主要api ...
- matlab的数值计算方法,数值计算方法中的一些常用算法的Matlab源码
数值计算方法中的一些常用算法的Matlab源码,这些程序都是原创,传上来仅供大家参考,不足之处请大家指正,切勿做其它用途-- 说明:这些程序都是脚本函数,不可直接运行,需要创建函数m文件,保存时文件名 ...
- spark源码解读3之RDD中top源码解读
更多代码请见:https://github.com/xubo245/SparkLearning spark源码解读系列环境:spark-2.0.1 (20161103github下载版) 1.理解 输 ...
- Fabric中PBFT源码解读 (3)
文章目录 5. Preprepare消息的接收以及Prepare消息的发送 6. Prepare消息的接收以及Commit消息的发送 5. Preprepare消息的接收以及Prepare消息的发送 ...
- Golang 中 Slice的分析与使用(含源码)
文章目录 1.slice结构体 2.slice初始化 3.append操作 4.slice截取 5.slice深拷贝 6.值传递还是引用传递 参考文献 众所周知,在golang中,slice(切片)是 ...
- Redis在Java中的使用及连接数据库(附源码)
Redis在Java中的使用及连接数据库(附源码) 引言: 本文主要分享了Redis如何在IDEA中部署,运行:模拟加入Redis的操作: 文章目录 Redis在Java中的使用及连接数据库(附源码) ...
- python删除链表中重复的节点_Java编程删除链表中重复的节点问题解决思路及源码分享...
一. 题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 二. 例子 输入链表:1->2->3->3->4->4-&g ...
- chrome浏览器开发者工具F12中某网站的sources下的源码如何批量保存?
目录 chrome浏览器 开发者工具F12中某网站的sources下的源码如何批量保存 1. 常用保存Sources源码的两种方法 1.1单个文件 1.2 单个页面 2. 问题 3.解决方案 chro ...
最新文章
- 美国人到底为什么不待见人脸识别技术?
- RS485,RS232,USB,Ethernet 传输速度分别是多少
- 工具坐标6点法_轻松学机器人系列之各坐标系关系
- 螺旋遍历_螺旋形式的水平阶遍历
- linux 命令 语法,linux常用命令及语法
- Rust+Yew之hello world
- DNS 基础知识及 Linux DNS 服务器操作知识
- Git 小问题:fatal: not a git repository (or any of the parent directories): .git
- c语言链表移动北理工,北京理工大学c语言网络教室 链表
- Android小说阅读器案例
- 基于Flask框架实现Mock Server
- Java项目《谷粒商城》高级篇 个人错误总结
- HBase 过滤器使用
- nyoj54小明的存钱计划
- 计算模拟I2C的传输速率
- vb wps 链接单元格_使用VB快速制作WPS的COM加载项
- go之官方依赖管理工具dep安装和使用
- 【MySQL】浅谈MySQL中索引的基本操作以及背后的数据结构
- Java使用iText PDF合并PDF(将多个PDF合并成一个PDF)
- 王者荣耀服务器什么时候增加人数,王者荣耀2020年健康系统新规则 王者荣耀未成年一天能玩几小时...
热门文章
- 信息系统项目时间管理案例之关键路径案例
- JS_全球国家json数据,中文名+英文名
- WIN7硬盘安装Ubuntu18.04双系统(免U盘)
- python3通过qq邮箱发送邮件以及附件
- ig夺冠后服务器不稳定,LOL官方为iG夺冠庆典活动道歉:服务器不稳致奖励延迟...
- 吉大19秋学期计算机应用基础在线作业,吉大11春学期《计算机应用基础》在线作业二答案...
- 海康、大华IpCamera摄像机 RTSP地址和格式
- Linux平台下Java调用C函数
- 043_《Delphi程序开发范例宝典(第2版)》
- 快速掌握正则表达式,掌握常用的就ok