摘要:前言使用插件機制加載各種組件,本文簡要分析插件機制實現注解注解提供了一種便捷的方法將一個類聲明成的插件,比如,單例類用來保存插件信息,暴露了一些方法從配置文件中加載內置插件,使用了單例設計模式線程安全的數據結構使用了一些多線程編程的最佳實踐
前言
log4j2 使用插件機制加載各種組件:appender, logger .etc,本文簡要分析 log4j2 插件機制實現
Plugin Annotation(注解)Plugin 注解提供了一種便捷的方法將一個類聲明成 log4j2 的插件,比如
@Plugin(name = "Console", category = "Core", elementType = "appender", printObject = true) public final class ConsoleAppender extends AbstractOutputStreamAppender{ ... }
name,name of the plugin
category, category to place the plugin under
name of the corresponding category of elements this plugin belongs under
Plugin Registry 單例PluginRegistry 類用來保存插件信息,暴露了一些方法從配置文件中加載(內置)插件,使用了單例設計模式
private static volatile PluginRegistry INSTANCE; private static final Object INSTANCE_LOCK = new Object(); private PluginRegistry() { } public static PluginRegistry getInstance() { PluginRegistry result = INSTANCE; if (result == null) { synchronized(INSTANCE_LOCK) { result = INSTANCE; if (result == null) { INSTANCE = result = new PluginRegistry(); } } } }線程安全的數據結構
PluginRegistry 使用了一些 Java 多線程編程的最佳實踐:
使用 AtomicReference 類的 CAS(compare and set)操作,避免在多線程環境下 插件配置 被多次加載
使用 ConcurrentMapHash 類替代 HashMap 提供線程安全的 map
PluginType 類用來描述插件,比如插件對應的 class
/** * Contains plugins found in Log4j2Plugins.dat cache files in the main CLASSPATH. */ private final AtomicReference
log4j2Plugins.dat 是插件描述文件,內部插件描述文件位于:
log4j-core-2.5.jar META-INF org.apache.logging.log4j.core.config.plugins Log4j2Plugins.dat加載插件
PluginRegistry 中和加載掃描插件相關的方法
loadFromMainClassLoader,加載內部插件
loadFromBundle,osgi相關
loadFromPackage,加載指定 package(包)中的插件
加載內部插件public Map加載指定包中插件>> loadFromMainClassLoader() { final Map >> existing = pluginsByCategoryRef.get(); // 如果 get 方法返回非空,說明已經通過 main class loader 加載過插件配置 if (existing != null) { // already loaded return existing; } // 從配置文件加載 插件配置 final Map >> newPluginsByCategory = decodeCacheFiles(Loader.getClassLoader()); // CAS if (pluginsByCategoryRef.compareAndSet(null, newPluginsByCategory)) { return newPluginsByCategory; } return pluginsByCategoryRef.get(); }
public MapPluginManager>> loadFromPackage(final String pkg) { // 參數校驗 if (Strings.isBlank(pkg)) { return Collections.emptyMap(); } // 如果 pkg 已經被加載過直接返回 Map >> existing = pluginByCategoryByPackage.get(pkg); if (existing != null) { return existing; } // 加載 pkg // 線程安全的 put if absent 操作(類似 CAS) existing = pluginsByCategoryByPackage.putIfAbsent(pkg, newPluginsByCategory); if (existing != null) { return existing; } return newPluginsByCategory; }
PluginManager 類用來加載和管理所有的插件,每一個 category(類別)都有一個對應的 PluginManager
public PluginManager(final String category) { this.category = category; }
collectPlugins 方法用于加載插件(描述信息)
public void collectPlugins(final List總結packages) { ... }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66792.html
摘要:前言一般都會對應用程序日志做回滾處理,本文簡要分析日志回滾實現觸發策略使用接口來抽象日志回滾觸發策略,使用了設計模式方法用于初始化策略,方法用于判斷是否需要回滾,接口的不同實現類對應不同的策略組合模式,聚合不同的策略類基于時間的回滾策略基于 前言 一般都會對應用程序日志做回滾處理,本文簡要分析 log4j2 日志回滾實現 觸發策略 log4j2 使用 TriggeringPolity ...
摘要:系列文章系列第一篇基礎雜記系列第二篇插件機制雜記系列第三篇流程雜記前言本身并不難,他所完成的各種復雜炫酷的功能都依賴于他的插件機制。的插件機制依賴于一個核心的庫,。是什么是一個類似于的的庫主要是控制鉤子函數的發布與訂閱。 系列文章 Webpack系列-第一篇基礎雜記 Webpack系列-第二篇插件機制雜記 Webpack系列-第三篇流程雜記 前言 webpack本身并不難,他所完成...
摘要:語法部分采用的是標準。那么整個播放器是怎么把播放器的加載到中的呢在的構造函數里可以看到先生成,然后初始化父類遍歷屬性,將中的類實例化并將對應的嵌入到的屬性中,最后在的構造函數中直接掛載到標簽的父級上。 video.js 源碼分析(JavaScript) 組織結構 繼承關系 運行機制 插件的運行機制 插件的定義 插件的運行 控制條是如何運行的 UI與JavaScript對象的...
摘要:語法部分采用的是標準。那么整個播放器是怎么把播放器的加載到中的呢在的構造函數里可以看到先生成,然后初始化父類遍歷屬性,將中的類實例化并將對應的嵌入到的屬性中,最后在的構造函數中直接掛載到標簽的父級上。 video.js 源碼分析(JavaScript) 組織結構 繼承關系 運行機制 插件的運行機制 插件的定義 插件的運行 控制條是如何運行的 UI與JavaScript對象的...
閱讀 2329·2021-09-29 09:42
閱讀 564·2021-09-06 15:02
閱讀 2616·2021-09-02 15:40
閱讀 2121·2019-08-30 14:23
閱讀 1865·2019-08-30 13:48
閱讀 1296·2019-08-26 12:01
閱讀 966·2019-08-26 11:53
閱讀 2153·2019-08-23 18:31