From a6f0b9ece9ba23185cf31b2cefd8341fb5e7f5fe Mon Sep 17 00:00:00 2001 From: wyl <959814898@qq.com> Date: Sun, 7 Aug 2022 23:22:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0ttl=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=AE=9E=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- concurrent/pom.xml | 8 - pom.xml | 5 + spring-boot/pom.xml | 1 + spring-boot/spring-boot-common/pom.xml | 4 + .../common/SpringBootCommonApplication.java | 1 - .../org/slf4j/LogLogbackTTLMdcAdapter.java | 146 ++++++++++++++++++ 6 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 spring-boot/spring-boot-common/src/main/java/org/slf4j/LogLogbackTTLMdcAdapter.java diff --git a/concurrent/pom.xml b/concurrent/pom.xml index 1684c33..79adf6a 100644 --- a/concurrent/pom.xml +++ b/concurrent/pom.xml @@ -16,17 +16,9 @@ 8 - - - org.junit.jupiter - junit-jupiter-api - 5.8.2 - test - com.alibaba transmittable-thread-local - 2.13.2 cn.hutool diff --git a/pom.xml b/pom.xml index e85aab5..02d4715 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,11 @@ xxl-job-core 2.3.0 + + com.alibaba + transmittable-thread-local + 2.13.2 + cn.hutool hutool-bom diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 16b2cd1..7d91e6a 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -37,6 +37,7 @@ mybatis-plus-boot-starter 3.3.2 + diff --git a/spring-boot/spring-boot-common/pom.xml b/spring-boot/spring-boot-common/pom.xml index 91cfc1e..8509a38 100644 --- a/spring-boot/spring-boot-common/pom.xml +++ b/spring-boot/spring-boot-common/pom.xml @@ -42,6 +42,10 @@ spring-boot-test test + + com.alibaba + transmittable-thread-local + diff --git a/spring-boot/spring-boot-common/src/main/java/com/wyl/spring/boot/common/SpringBootCommonApplication.java b/spring-boot/spring-boot-common/src/main/java/com/wyl/spring/boot/common/SpringBootCommonApplication.java index 3106988..caa1fd2 100644 --- a/spring-boot/spring-boot-common/src/main/java/com/wyl/spring/boot/common/SpringBootCommonApplication.java +++ b/spring-boot/spring-boot-common/src/main/java/com/wyl/spring/boot/common/SpringBootCommonApplication.java @@ -5,7 +5,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.EnableAspectJAutoProxy; -import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication @EnableAspectJAutoProxy(exposeProxy = true) diff --git a/spring-boot/spring-boot-common/src/main/java/org/slf4j/LogLogbackTTLMdcAdapter.java b/spring-boot/spring-boot-common/src/main/java/org/slf4j/LogLogbackTTLMdcAdapter.java new file mode 100644 index 0000000..45fcaa1 --- /dev/null +++ b/spring-boot/spring-boot-common/src/main/java/org/slf4j/LogLogbackTTLMdcAdapter.java @@ -0,0 +1,146 @@ +package org.slf4j; + +import com.alibaba.ttl.TransmittableThreadLocal; +import org.slf4j.spi.MDCAdapter; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * 针对于Logback日志的mdc adapter。 + * + * @author Bryan.Zhang + * @since 1.3.7 + */ +public class LogLogbackTTLMdcAdapter implements MDCAdapter { + + final ThreadLocal> copyOnInheritThreadLocal = new TransmittableThreadLocal<>(); + + private static final int WRITE_OPERATION = 1; + private static final int READ_OPERATION = 2; + + private static LogLogbackTTLMdcAdapter mdcMDCAdapter; + + // keeps track of the last operation performed + final ThreadLocal lastOperation = new ThreadLocal<>(); + + static { + mdcMDCAdapter = new LogLogbackTTLMdcAdapter(); + MDC.mdcAdapter = mdcMDCAdapter; + } + + public static MDCAdapter getInstance() { + return mdcMDCAdapter; + } + + private Integer getAndSetLastOperation(int op) { + Integer lastOp = lastOperation.get(); + lastOperation.set(op); + return lastOp; + } + + private static boolean wasLastOpReadOrNull(Integer lastOp) { + return lastOp == null || lastOp == READ_OPERATION; + } + + private Map duplicateAndInsertNewMap(Map oldMap) { + Map newMap = Collections.synchronizedMap(new HashMap()); + if (oldMap != null) { + // we don't want the parent thread modifying oldMap while we are + // iterating over it + synchronized (oldMap) { + newMap.putAll(oldMap); + } + } + + copyOnInheritThreadLocal.set(newMap); + return newMap; + } + + @Override + public void put(String key, String val) { + if (key == null) { + throw new IllegalArgumentException("key cannot be null"); + } + + Map oldMap = copyOnInheritThreadLocal.get(); + Integer lastOp = getAndSetLastOperation(WRITE_OPERATION); + + if (wasLastOpReadOrNull(lastOp) || oldMap == null) { + Map newMap = duplicateAndInsertNewMap(oldMap); + newMap.put(key, val); + } else { + oldMap.put(key, val); + } + } + + @Override + public void remove(String key) { + if (key == null) { + return; + } + Map oldMap = copyOnInheritThreadLocal.get(); + if (oldMap == null) { + return; + } + + Integer lastOp = getAndSetLastOperation(WRITE_OPERATION); + + if (wasLastOpReadOrNull(lastOp)) { + Map newMap = duplicateAndInsertNewMap(oldMap); + newMap.remove(key); + } else { + oldMap.remove(key); + } + + } + + + @Override + public void clear() { + lastOperation.set(WRITE_OPERATION); + copyOnInheritThreadLocal.remove(); + } + + @Override + public String get(String key) { + Map map = getPropertyMap(); + if ((map != null) && (key != null)) { + return map.get(key); + } else { + return null; + } + } + + public Map getPropertyMap() { + lastOperation.set(READ_OPERATION); + return copyOnInheritThreadLocal.get(); + } + + + @Override + public Map getCopyOfContextMap() { + lastOperation.set(READ_OPERATION); + Map hashMap = copyOnInheritThreadLocal.get(); + if (hashMap == null) { + return null; + } else { + return new HashMap<>(hashMap); + } + } + + @SuppressWarnings("unchecked") + @Override + public void setContextMap(Map contextMap) { + lastOperation.set(WRITE_OPERATION); + + Map newMap = Collections.synchronizedMap(new HashMap<>()); + newMap.putAll(contextMap); + + // the newMap replaces the old one for serialisation's sake + copyOnInheritThreadLocal.set(newMap); + + + } +}