最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Logback MDCAdapter日志跟蹤及自定義效果源碼解讀

 更新時(shí)間:2023年11月12日 09:02:42   作者:codecraft  
這篇文章主要為大家介紹了Logback MDCAdapter日志跟蹤及自定義效果源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下LogbackMDCAdapter

MDCAdapter

org/slf4j/spi/MDCAdapter.java

public interface MDCAdapter {
    /**
     * Put a context value (the <code>val</code> parameter) as identified with
     * the <code>key</code> parameter into the current thread's context map. 
     * The <code>key</code> parameter cannot be null. The <code>val</code> parameter
     * can be null only if the underlying implementation supports it.
     * 
     * <p>If the current thread does not have a context map it is created as a side
     * effect of this call.
     */
    public void put(String key, String val);
    /**
     * Get the context identified by the <code>key</code> parameter.
     * The <code>key</code> parameter cannot be null.
     * 
     * @return the string value identified by the <code>key</code> parameter.
     */
    public String get(String key);
    /**
     * Remove the context identified by the <code>key</code> parameter.
     * The <code>key</code> parameter cannot be null. 
     * 
     * <p>
     * This method does nothing if there is no previous value 
     * associated with <code>key</code>.
     */
    public void remove(String key);
    /**
     * Clear all entries in the MDC.
     */
    public void clear();
    /**
     * Return a copy of the current thread's context map, with keys and 
     * values of type String. Returned value may be null.
     * 
     * @return A copy of the current thread's context map. May be null.
     * @since 1.5.1
     */
    public Map<String, String> getCopyOfContextMap();
    /**
     * Set the current thread's context map by first clearing any existing 
     * map and then copying the map passed as parameter. The context map 
     * parameter must only contain keys and values of type String.
     * 
     * Implementations must support null valued map passed as parameter.
     * 
     * @param contextMap must contain only keys and values of type String
     * 
     * @since 1.5.1
     */
    public void setContextMap(Map<String, String> contextMap);
    /**
     * Push a value into the deque(stack) referenced by 'key'.
     *      
     * @param key identifies the appropriate stack
     * @param value the value to push into the stack
     * @since 2.0.0
     */
    public void pushByKey(String key, String value);
    /**
     * Pop the stack referenced by 'key' and return the value possibly null.
     * 
     * @param key identifies the deque(stack)
     * @return the value just popped. May be null/
     * @since 2.0.0
     */
    public String popByKey(String key);
    /**
     * Returns a copy of the deque(stack) referenced by 'key'. May be null.
     * 
     * @param key identifies the  stack
     * @return copy of stack referenced by 'key'. May be null.
     * 
     * @since 2.0.0
     */
    public Deque<String>  getCopyOfDequeByKey(String key);
    /**
     * Clear the deque(stack) referenced by 'key'. 
     * 
     * @param key identifies the  stack
     * 
     * @since 2.0.0
     */
    public void clearDequeByKey(String key);
}
slf4j定義了MDCAdapter接口,該接口定義了put、get、remove、clear、getCopyOfContextMap、setContextMap、pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey方法

LogbackMDCAdapter

ch/qos/logback/classic/util/LogbackMDCAdapter.java

public class LogbackMDCAdapter implements MDCAdapter  {
    // BEWARE: Keys or values placed in a ThreadLocal should not be of a type/class
    // not included in the JDK. See also https://jira.qos.ch/browse/LOGBACK-450
    final ThreadLocal<Map<String, String>> readWriteThreadLocalMap = new ThreadLocal<Map<String, String>>();
    final ThreadLocal<Map<String, String>> readOnlyThreadLocalMap = new ThreadLocal<Map<String, String>>();
    private final ThreadLocalMapOfStacks threadLocalMapOfDeques = new ThreadLocalMapOfStacks();
    //......
}
LogbackMDCAdapter實(shí)現(xiàn)了MDCAdapter接口,它基于readWriteThreadLocalMap、readOnlyThreadLocalMap、threadLocalMapOfDeques來(lái)實(shí)現(xiàn)

readWriteThreadLocalMap

public void put(String key, String val) throws IllegalArgumentException {
        if (key == null) {
            throw new IllegalArgumentException("key cannot be null");
        }
        Map<String, String> current = readWriteThreadLocalMap.get();
        if (current == null) {
            current = new HashMap<String, String>();
            readWriteThreadLocalMap.set(current);
        }
        current.put(key, val);
        nullifyReadOnlyThreadLocalMap();
    }
    @Override
    public String get(String key) {
        Map<String, String> hashMap = readWriteThreadLocalMap.get();
        if ((hashMap != null) && (key != null)) {
            return hashMap.get(key);
        } else {
            return null;
        }
    }
    @Override
    public void remove(String key) {
        if (key == null) {
            return;
        }
        Map<String, String> current = readWriteThreadLocalMap.get();
        if (current != null) {
            current.remove(key);
            nullifyReadOnlyThreadLocalMap();
        }
    }
    @Override
    public void clear() {
        readWriteThreadLocalMap.set(null);
        nullifyReadOnlyThreadLocalMap();
    }
    private void nullifyReadOnlyThreadLocalMap() {
        readOnlyThreadLocalMap.set(null);
    }  
    public void setContextMap(Map contextMap) {
        if (contextMap != null) {
            readWriteThreadLocalMap.set(new HashMap<String, String>(contextMap));
        } else {
            readWriteThreadLocalMap.set(null);
        }
        nullifyReadOnlyThreadLocalMap();
    }
put、get、remove、clear、setContextMap都是基于readWriteThreadLocalMap,同時(shí)修改操作會(huì)同時(shí)調(diào)用nullifyReadOnlyThreadLocalMap,將readOnlyThreadLocalMap設(shè)置為null

getCopyOfContextMap

public Map getCopyOfContextMap() {
        Map<String, String> readOnlyMap = getPropertyMap();
        if (readOnlyMap == null) {
            return null;
        } else {
            return new HashMap<String, String>(readOnlyMap);
        }
    }

    public Map<String, String> getPropertyMap() {
        Map<String, String> readOnlyMap = readOnlyThreadLocalMap.get();
        if (readOnlyMap == null) {
            Map<String, String> current = readWriteThreadLocalMap.get();
            if (current != null) {
                final Map<String, String> tempMap = new HashMap<String, String>(current);
                readOnlyMap = Collections.unmodifiableMap(tempMap);
                readOnlyThreadLocalMap.set(readOnlyMap);
            }
        }
        return readOnlyMap;
    }
getCopyOfContextMap方法通過(guò)getPropertyMap獲取,如果不為null則新創(chuàng)建HashMap返回;getPropertyMap先從readOnlyThreadLocalMap讀取,如果readOnlyThreadLocalMap為null則從readWriteThreadLocalMap拷貝一份unmodifiableMap,并設(shè)置到readOnlyThreadLocalMap

threadLocalMapOfDeques

@Override
    public void pushByKey(String key, String value) {
        threadLocalMapOfDeques.pushByKey(key, value);
    }
    @Override
    public String popByKey(String key) {
        return threadLocalMapOfDeques.popByKey(key);
    }
    @Override
    public Deque<String> getCopyOfDequeByKey(String key) {
        return threadLocalMapOfDeques.getCopyOfDequeByKey(key);
    }
    @Override
    public void clearDequeByKey(String key) {
        threadLocalMapOfDeques.clearDequeByKey(key);
    }
pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey均是基于threadLocalMapOfDeques,它是ThreadLocalMapOfStacks類(lèi)型

ThreadLocalMapOfStacks

org/slf4j/helpers/ThreadLocalMapOfStacks.java

public class ThreadLocalMapOfStacks {
    // BEWARE: Keys or values placed in a ThreadLocal should not be of a type/class
    // not included in the JDK. See also https://jira.qos.ch/browse/LOGBACK-450
    final ThreadLocal<Map<String, Deque<String>>> tlMapOfStacks = new ThreadLocal<>();
    public void pushByKey(String key, String value) {
        if (key == null)
            return;
        Map<String, Deque<String>> map = tlMapOfStacks.get();
        if (map == null) {
            map = new HashMap<>();
            tlMapOfStacks.set(map);
        }
        Deque<String> deque = map.get(key);
        if (deque == null) {
            deque = new ArrayDeque<>();
        }
        deque.push(value);
        map.put(key, deque);
    }
    public String popByKey(String key) {
        if (key == null)
            return null;
        Map<String, Deque<String>> map = tlMapOfStacks.get();
        if (map == null)
            return null;
        Deque<String> deque = map.get(key);
        if (deque == null)
            return null;
        return deque.pop();
    }
    public Deque<String> getCopyOfDequeByKey(String key) {
        if (key == null)
            return null;
        Map<String, Deque<String>> map = tlMapOfStacks.get();
        if (map == null)
            return null;
        Deque<String> deque = map.get(key);
        if (deque == null)
            return null;
        return new ArrayDeque<String>(deque);
    }
    /**
     * Clear the deque(stack) referenced by 'key'. 
     * 
     * @param key identifies the  stack
     * 
     * @since 2.0.0
     */
    public void clearDequeByKey(String key) {
        if (key == null)
            return;
        Map<String, Deque<String>> map = tlMapOfStacks.get();
        if (map == null)
            return;
        Deque<String> deque = map.get(key);
        if (deque == null)
            return;
        deque.clear();
    }
}
ThreadLocalMapOfStacks是slf4j定義的,基于ThreadLocal<Map<String, Deque<String>>>實(shí)現(xiàn)的

小結(jié)

slf4j定義了MDCAdapter接口,該接口定義了put、get、remove、clear、getCopyOfContextMap、setContextMap、pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey方法;LogbackMDCAdapter實(shí)現(xiàn)了MDCAdapter接口,它基于readWriteThreadLocalMap、readOnlyThreadLocalMap、threadLocalMapOfDeques來(lái)實(shí)現(xiàn),其中put、get、remove、clear、setContextMap都是基于readWriteThreadLocalMap,pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey均是基于threadLocalMapOfDeques。

以上就是Logback MDCAdapter日志跟蹤及自定義效果源碼解讀的詳細(xì)內(nèi)容,更多關(guān)于Logback MDCAdapter日志跟蹤的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java深入理解代碼塊的使用細(xì)節(jié)

    Java深入理解代碼塊的使用細(xì)節(jié)

    所謂代碼塊是指用"{}"括起來(lái)的一段代碼,根據(jù)其位置和聲明的不同,可以分為普通代碼塊、構(gòu)造塊、靜態(tài)塊、和同步代碼塊。如果在代碼塊前加上?synchronized關(guān)鍵字,則此代碼塊就成為同步代碼塊
    2022-05-05
  • Spring Security OAuth 自定義授權(quán)方式實(shí)現(xiàn)手機(jī)驗(yàn)證碼

    Spring Security OAuth 自定義授權(quán)方式實(shí)現(xiàn)手機(jī)驗(yàn)證碼

    這篇文章主要介紹了Spring Security OAuth 自定義授權(quán)方式實(shí)現(xiàn)手機(jī)驗(yàn)證碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Springboot集成shiro之登錄攔截/權(quán)限控制方式

    Springboot集成shiro之登錄攔截/權(quán)限控制方式

    文章介紹了Shiro框架的的配置和使用,包括添加依賴、配置ShiroConfig、創(chuàng)建realm、配置安全管理器、配置過(guò)濾器和權(quán)限控制,還介紹了配置ehcache緩存、自定義加密和處理404重定向等問(wèn)題,總結(jié)了Shiro框架中的常用配置和解決常見(jiàn)問(wèn)題的方法
    2026-05-05
  • Java基本語(yǔ)法小白入門(mén)級(jí)

    Java基本語(yǔ)法小白入門(mén)級(jí)

    Java基本語(yǔ)法就是指java中的規(guī)則,也是一種語(yǔ)言規(guī)則,規(guī)范,同時(shí)也能讓您在后面的學(xué)習(xí)中避免不必要的一些錯(cuò)誤和麻煩,是您學(xué)好java必修的第一門(mén)課程
    2023-05-05
  • SpringBoot中的自定義FailureAnalyzer詳解

    SpringBoot中的自定義FailureAnalyzer詳解

    這篇文章主要介紹了SpringBoot中的自定義FailureAnalyzer詳解,FailureAnalyzer是一種很好的方式在啟動(dòng)時(shí)攔截異常并將其轉(zhuǎn)換為易讀的消息,并將其包含在FailureAnalysis中, Spring Boot為應(yīng)用程序上下文相關(guān)異常、JSR-303驗(yàn)證等提供了此類(lèi)分析器,需要的朋友可以參考下
    2023-12-12
  • 解析Tomcat 6、7在EL表達(dá)式解析時(shí)存在的一個(gè)Bug

    解析Tomcat 6、7在EL表達(dá)式解析時(shí)存在的一個(gè)Bug

    這篇文章主要是對(duì)Tomcat 6、7在EL表達(dá)式解析時(shí)存在的一個(gè)Bug進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-12-12
  • Spring深入刨析聲明式事務(wù)

    Spring深入刨析聲明式事務(wù)

    在spring注解中,使用聲明式事務(wù),需要用到兩個(gè)核心的注解:@Transactional注解和@EnableTransactionManagement注解。將@Transactional注解加在方法上,@EnableTransactionManagement注解加在配置類(lèi)上
    2022-12-12
  • 解析Idea為什么不推薦使用@Autowired進(jìn)行Field注入

    解析Idea為什么不推薦使用@Autowired進(jìn)行Field注入

    這篇文章主要介紹了Idea不推薦使用@Autowired進(jìn)行Field注入的原因,網(wǎng)上文章大部分都是介紹兩者的區(qū)別,沒(méi)有提到為什么,當(dāng)時(shí)想了好久想出了可能的原因,今天來(lái)總結(jié)一下
    2022-05-05
  • clickhouse?批量插入數(shù)據(jù)及ClickHouse常用命令詳解

    clickhouse?批量插入數(shù)據(jù)及ClickHouse常用命令詳解

    這篇文章主要介紹了clickhouse?批量插入數(shù)據(jù)及ClickHouse常用命令,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Java動(dòng)態(tài)規(guī)劃之編輯距離問(wèn)題示例代碼

    Java動(dòng)態(tài)規(guī)劃之編輯距離問(wèn)題示例代碼

    這篇文章主要介紹了Java動(dòng)態(tài)規(guī)劃之編輯距離問(wèn)題示例代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11

最新評(píng)論

丰城市| 冀州市| 邳州市| 乐至县| 呼和浩特市| 修武县| 焉耆| 缙云县| 册亨县| 库尔勒市| 南通市| 乌拉特前旗| 防城港市| 锦屏县| 尼木县| 乌恰县| 阜新| 鄂尔多斯市| 田东县| 武强县| 兴业县| 江孜县| 兰州市| 荃湾区| 宁南县| 宁远县| 濮阳县| 泽州县| 英德市| 临猗县| 桐梓县| 富阳市| 临夏县| 上林县| 甘泉县| 乐业县| 扶风县| 泰安市| 聂荣县| 雅江县| 巫山县|