国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Log42j 源代碼分析:plugin(插件)機(jī)制

learning / 1591人閱讀

摘要:前言使用插件機(jī)制加載各種組件,本文簡要分析插件機(jī)制實現(xiàn)注解注解提供了一種便捷的方法將一個類聲明成的插件,比如,單例類用來保存插件信息,暴露了一些方法從配置文件中加載內(nèi)置插件,使用了單例設(shè)計模式線程安全的數(shù)據(jù)結(jié)構(gòu)使用了一些多線程編程的最佳實踐

前言

log4j2 使用插件機(jī)制加載各種組件:appender, logger .etc,本文簡要分析 log4j2 插件機(jī)制實現(xiàn)

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 類用來保存插件信息,暴露了一些方法從配置文件中加載(內(nèi)置)插件,使用了單例設(shè)計模式

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();
            }
        }
    }
}
線程安全的數(shù)據(jù)結(jié)構(gòu)

PluginRegistry 使用了一些 Java 多線程編程的最佳實踐:

使用 AtomicReference 類的 CAS(compare and set)操作,避免在多線程環(huán)境下 插件配置 被多次加載

使用 ConcurrentMapHash 類替代 HashMap 提供線程安全的 map

PluginType 類用來描述插件,比如插件對應(yīng)的 class

    /**
     * Contains plugins found in Log4j2Plugins.dat cache files in the main CLASSPATH.
     */
    private final AtomicReference>>> pluginsByCategoryRef =
        new AtomicReference<>();

    /**
     * Contains plugins found in Log4j2Plugins.dat cache files in OSGi Bundles.
     */
    private final ConcurrentMap>>> pluginsByCategoryByBundleId =
        new ConcurrentHashMap<>();

    /**
     * Contains plugins found by searching for annotated classes at runtime.
     */
    private final ConcurrentMap>>> pluginsByCategoryByPackage =
        new ConcurrentHashMap<>();

log4j2Plugins.dat 是插件描述文件,內(nèi)部插件描述文件位于:

log4j-core-2.5.jar
    META-INF
        org.apache.logging.log4j.core.config.plugins
            Log4j2Plugins.dat
加載插件

PluginRegistry 中和加載掃描插件相關(guān)的方法

loadFromMainClassLoader,加載內(nèi)部插件

loadFromBundle,osgi相關(guān)

loadFromPackage,加載指定 package(包)中的插件

加載內(nèi)部插件
    public Map>> loadFromMainClassLoader() {
        final Map>> existing = pluginsByCategoryRef.get();
        // 如果 get 方法返回非空,說明已經(jīng)通過 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 Map>> loadFromPackage(final String pkg) {
    // 參數(shù)校驗
    if (Strings.isBlank(pkg)) {
        return Collections.emptyMap();
    }

    // 如果 pkg 已經(jīng)被加載過直接返回
    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

PluginManager 類用來加載和管理所有的插件,每一個 category(類別)都有一個對應(yīng)的 PluginManager

public PluginManager(final String category) {
    this.category = category;
}

collectPlugins 方法用于加載插件(描述信息)

public void collectPlugins(final List packages) {
    ...
}
總結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/66792.html

相關(guān)文章

  • Log42j 代碼分析:日志回滾

    摘要:前言一般都會對應(yīng)用程序日志做回滾處理,本文簡要分析日志回滾實現(xiàn)觸發(fā)策略使用接口來抽象日志回滾觸發(fā)策略,使用了設(shè)計模式方法用于初始化策略,方法用于判斷是否需要回滾,接口的不同實現(xiàn)類對應(yīng)不同的策略組合模式,聚合不同的策略類基于時間的回滾策略基于 前言 一般都會對應(yīng)用程序日志做回滾處理,本文簡要分析 log4j2 日志回滾實現(xiàn) 觸發(fā)策略 log4j2 使用 TriggeringPolity ...

    libin19890520 評論0 收藏0
  • webpack系列-插件機(jī)制雜記

    摘要:系列文章系列第一篇基礎(chǔ)雜記系列第二篇插件機(jī)制雜記系列第三篇流程雜記前言本身并不難,他所完成的各種復(fù)雜炫酷的功能都依賴于他的插件機(jī)制。的插件機(jī)制依賴于一個核心的庫,。是什么是一個類似于的的庫主要是控制鉤子函數(shù)的發(fā)布與訂閱。 系列文章 Webpack系列-第一篇基礎(chǔ)雜記 Webpack系列-第二篇插件機(jī)制雜記 Webpack系列-第三篇流程雜記 前言 webpack本身并不難,他所完成...

    Neilyo 評論0 收藏0
  • video.js 源碼分析(JavaScript)

    摘要:語法部分采用的是標(biāo)準(zhǔn)。那么整個播放器是怎么把播放器的加載到中的呢在的構(gòu)造函數(shù)里可以看到先生成,然后初始化父類遍歷屬性,將中的類實例化并將對應(yīng)的嵌入到的屬性中,最后在的構(gòu)造函數(shù)中直接掛載到標(biāo)簽的父級上。 video.js 源碼分析(JavaScript) 組織結(jié)構(gòu) 繼承關(guān)系 運(yùn)行機(jī)制 插件的運(yùn)行機(jī)制 插件的定義 插件的運(yùn)行 控制條是如何運(yùn)行的 UI與JavaScript對象的...

    Neilyo 評論0 收藏0
  • video.js 源碼分析(JavaScript)

    摘要:語法部分采用的是標(biāo)準(zhǔn)。那么整個播放器是怎么把播放器的加載到中的呢在的構(gòu)造函數(shù)里可以看到先生成,然后初始化父類遍歷屬性,將中的類實例化并將對應(yīng)的嵌入到的屬性中,最后在的構(gòu)造函數(shù)中直接掛載到標(biāo)簽的父級上。 video.js 源碼分析(JavaScript) 組織結(jié)構(gòu) 繼承關(guān)系 運(yùn)行機(jī)制 插件的運(yùn)行機(jī)制 插件的定義 插件的運(yùn)行 控制條是如何運(yùn)行的 UI與JavaScript對象的...

    simpleapples 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<