聊聊LogbackMDCAdapter

编程入门 行业动态 更新时间:2024-10-27 21:16:21

聊聊LogbackMDCAdapter

聊聊LogbackMDCAdapter

本文主要研究一下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  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实现了MDCAdapter接口,它基于readWriteThreadLocalMap、readOnlyThreadLocalMap、threadLocalMapOfDeques来实现

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();}@Overridepublic String get(String key) {Map<String, String> hashMap = readWriteThreadLocalMap.get();if ((hashMap != null) && (key != null)) {return hashMap.get(key);} else {return null;}}@Overridepublic void remove(String key) {if (key == null) {return;}Map<String, String> current = readWriteThreadLocalMap.get();if (current != null) {current.remove(key);nullifyReadOnlyThreadLocalMap();}}@Overridepublic 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,同时修改操作会同时调用nullifyReadOnlyThreadLocalMap,将readOnlyThreadLocalMap设置为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方法通过getPropertyMap获取,如果不为null则新创建HashMap返回;getPropertyMap先从readOnlyThreadLocalMap读取,如果readOnlyThreadLocalMap为null则从readWriteThreadLocalMap拷贝一份unmodifiableMap,并设置到readOnlyThreadLocalMap

threadLocalMapOfDeques

    @Overridepublic void pushByKey(String key, String value) {threadLocalMapOfDeques.pushByKey(key, value);}@Overridepublic String popByKey(String key) {return threadLocalMapOfDeques.popByKey(key);}@Overridepublic Deque<String> getCopyOfDequeByKey(String key) {return threadLocalMapOfDeques.getCopyOfDequeByKey(key);}@Overridepublic void clearDequeByKey(String key) {threadLocalMapOfDeques.clearDequeByKey(key);}

pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey均是基于threadLocalMapOfDeques,它是ThreadLocalMapOfStacks类型

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  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>>>实现的

小结

slf4j定义了MDCAdapter接口,该接口定义了put、get、remove、clear、getCopyOfContextMap、setContextMap、pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey方法;LogbackMDCAdapter实现了MDCAdapter接口,它基于readWriteThreadLocalMap、readOnlyThreadLocalMap、threadLocalMapOfDeques来实现,其中put、get、remove、clear、setContextMap都是基于readWriteThreadLocalMap,pushByKey、popByKey、getCopyOfDequeByKey、clearDequeByKey均是基于threadLocalMapOfDeques。

更多推荐

聊聊LogbackMDCAdapter

本文发布于:2023-11-15 08:14:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1596515.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:LogbackMDCAdapter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!