diff --git a/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonHelper.java b/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonHelper.java index b764a31e9..0078f7e36 100644 --- a/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonHelper.java +++ b/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonHelper.java @@ -18,6 +18,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.alipay.sofa.rpc.common.utils.ClassUtils; @@ -27,6 +28,8 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; +import static com.alipay.sofa.rpc.common.utils.ClassLoaderUtils.getCurrentClassLoader; + /** * @author zhiyuan.lzy */ @@ -37,12 +40,12 @@ public class JacksonHelper { /** * Request service and method cache {service+method:class} */ - private ConcurrentHashMap requestClassCache = new ConcurrentHashMap(); + private ConcurrentHashMap> requestClassCache = new ConcurrentHashMap<>(); /** * Response service and method cache {service+method:class} */ - private ConcurrentHashMap responseClassCache = new ConcurrentHashMap(); + private ConcurrentHashMap> responseClassCache = new ConcurrentHashMap<>(); /** * Fetch request class for cache according service and method @@ -54,14 +57,30 @@ public class JacksonHelper { public JavaType[] getReqClass(String service, String methodName) { String key = buildMethodKey(service, methodName); - Type[] reqClassList = requestClassCache.get(key); + Type[] reqClassList = getRequestCache().get(key); if (reqClassList == null) { //read interface and method from cache String interfaceClass = ConfigUniqueNameGenerator.getInterfaceName(service); Class clazz = ClassUtils.forName(interfaceClass, true); loadClassToCache(key, clazz, methodName); } - return requestClassCache.get(key); + return getRequestCache().get(key); + } + + private Map getRequestCache() { + return requestClassCache.computeIfAbsent(getCurrentClassLoader(), k -> new ConcurrentHashMap<>()); + } + + private Map getResponseCache() { + return responseClassCache.computeIfAbsent(getCurrentClassLoader(), k -> new ConcurrentHashMap<>()); + } + + public void clearCache(ClassLoader classLoader) { + if (classLoader == null) { + return; + } + requestClassCache.remove(classLoader); + responseClassCache.remove(classLoader); } /** @@ -73,14 +92,14 @@ public JavaType[] getReqClass(String service, String methodName) { */ public JavaType getResClass(String service, String methodName) { String key = service + "#" + methodName; - JavaType reqType = responseClassCache.get(key); + JavaType reqType = getResponseCache().get(key); if (reqType == null) { // 读取接口里的方法参数和返回值 String interfaceClass = ConfigUniqueNameGenerator.getInterfaceName(service); Class clazz = ClassUtils.forName(interfaceClass, true); loadClassToCache(key, clazz, methodName); } - return responseClassCache.get(key); + return getResponseCache().get(key); } /** @@ -122,7 +141,7 @@ private void loadClassToCache(String key, Class clazz, String methodName) { JavaType javaType = mapper.getTypeFactory().constructType(parameterTypes[i]); javaTypes[i] = javaType; } - requestClassCache.put(key, javaTypes); + getRequestCache().put(key, javaTypes); // parse response types Type resType = jsonMethod.getGenericReturnType(); @@ -130,6 +149,6 @@ private void loadClassToCache(String key, Class clazz, String methodName) { throw new SofaRpcRuntimeException(LogCodes.getLog(LogCodes.ERROR_VOID_RETURN, "jackson", clazz.getName())); } JavaType resJavaType = mapper.getTypeFactory().constructType(resType); - responseClassCache.put(key, resJavaType); + getResponseCache().put(key, resJavaType); } } diff --git a/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonSerializer.java b/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonSerializer.java index 66ebb5741..1f9ded9ff 100644 --- a/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonSerializer.java +++ b/codec/codec-jackson/src/main/java/com/alipay/sofa/rpc/codec/jackson/JacksonSerializer.java @@ -395,4 +395,7 @@ protected ObjectMapper getMapper() { return this.mapper; } + public void clearCache(ClassLoader classLoader) { + jacksonHelper.clearCache(classLoader); + } }