diff --git a/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java b/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java
index 062c2c223..f9a02c8f5 100644
--- a/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java
+++ b/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java
@@ -195,7 +195,7 @@ public static void putMethodCache(String serviceName, Method method) {
cache = old;
}
}
- cache.putIfAbsent(method.getName(), method);
+ cache.put(method.getName(), method);
}
/**
@@ -236,7 +236,7 @@ public static void putMethodSigsCache(String serviceName, String methodName, Str
cacheSigs = old;
}
}
- cacheSigs.putIfAbsent(methodName, argSigs);
+ cacheSigs.put(methodName, argSigs);
}
/**
@@ -289,7 +289,7 @@ public static void putOverloadMethodCache(String serviceName, Method method) {
for (Class> paramType : method.getParameterTypes()) {
mSigs.append(paramType.getName());
}
- cache.putIfAbsent(mSigs.toString(), method);
+ cache.put(mSigs.toString(), method);
}
/**
diff --git a/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java b/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java
new file mode 100644
index 000000000..624b06a3a
--- /dev/null
+++ b/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alipay.sofa.rpc.common.cache;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author zhangchengxi
+ */
+public class ReflectCacheTest {
+
+ @After
+ public void teardown() {
+ ReflectCache.clearAll();
+ }
+
+ @Test
+ public void putOverloadMethodCache() throws NoSuchMethodException {
+ Method hashCode1 = String.class.getMethod("hashCode");
+ Method hashCode2 = Object.class.getMethod("hashCode");
+ ReflectCache.putOverloadMethodCache("service", hashCode1);
+ Assert.assertSame(hashCode1, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[] {}));
+
+ ReflectCache.putOverloadMethodCache("service", hashCode2);
+ Assert.assertSame(hashCode2, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[] {}));
+ }
+
+ @Test
+ public void putMethodCache() throws NoSuchMethodException {
+ Method hashCode1 = String.class.getMethod("hashCode");
+ Method hashCode2 = Object.class.getMethod("hashCode");
+ ReflectCache.putMethodCache("service", hashCode1);
+ Assert.assertSame(hashCode1, ReflectCache.getMethodCache("service", "hashCode"));
+
+ ReflectCache.putMethodCache("service", hashCode2);
+ Assert.assertSame(hashCode2, ReflectCache.getMethodCache("service", "hashCode"));
+ }
+
+ @Test
+ public void putMethodSigsCache() throws NoSuchMethodException {
+ String[] sign1 = { "a" };
+ String[] sign2 = { "b" };
+ ReflectCache.putMethodSigsCache("service", "hashCode", sign1);
+ Assert.assertSame(sign1, ReflectCache.getMethodSigsCache("service", "hashCode"));
+
+ ReflectCache.putMethodSigsCache("service", "hashCode", sign2);
+ Assert.assertSame(sign2, ReflectCache.getMethodSigsCache("service", "hashCode"));
+ }
+}
\ No newline at end of file
diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java
index 30a283b64..00c06f150 100644
--- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java
+++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java
@@ -21,6 +21,7 @@
import com.alipay.sofa.rpc.common.cache.ReflectCache;
import com.alipay.sofa.rpc.common.utils.ClassTypeUtils;
import com.alipay.sofa.rpc.common.utils.ClassUtils;
+import com.alipay.sofa.rpc.config.ConfigUniqueNameGenerator;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.core.exception.RpcErrorType;
import com.alipay.sofa.rpc.core.exception.SofaRpcException;
@@ -30,7 +31,6 @@
import com.alipay.sofa.rpc.invoke.Invoker;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;
-import com.alipay.sofa.rpc.message.MessageBuilder;
import com.alipay.sofa.rpc.tracer.sofatracer.TracingContextKey;
import com.alipay.sofa.rpc.transport.ByteArrayWrapperByteBuf;
import com.google.protobuf.ByteString;
@@ -53,31 +53,36 @@ public class GenericServiceImpl extends SofaGenericServiceTriple.GenericServiceI
private static final Logger LOGGER = LoggerFactory.getLogger(GenericServiceImpl.class);
protected Invoker invoker;
- protected Class proxyClass;
+ protected ProviderConfig providerConfig;
- public GenericServiceImpl(Invoker invoker, Class proxyClass) {
+ public GenericServiceImpl(Invoker invoker, ProviderConfig providerConfig) {
super();
this.invoker = invoker;
- this.proxyClass = proxyClass; // todo use reflect to get Class
+ this.providerConfig = providerConfig;
+ String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig);
+ // 缓存接口的方法
+ for (Method m : providerConfig.getProxyClass().getMethods()) {
+ ReflectCache.putOverloadMethodCache(key, m);
+ }
}
@Override
public void generic(Request request, StreamObserver responseObserver) {
- SofaRequest sofaRequest = TracingContextKey.getKeySofaRequest().get(Context.current());
+ ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+ SofaRequest sofaRequest = TracingContextKey.getKeySofaRequest().get(Context.current());
String methodName = sofaRequest.getMethodName();
- String interfaceName = sofaRequest.getInterfaceName();
- ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
try {
- Class proxyClass = ClassTypeUtils.getClass(interfaceName);
- ClassLoader interfaceClassLoader = proxyClass.getClassLoader();
+ String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig);
+ ClassLoader interfaceClassLoader = providerConfig.getProxyClass().getClassLoader();
Thread.currentThread().setContextClassLoader(interfaceClassLoader);
Class[] argTypes = getArgTypes(request);
Serializer serializer = SerializerFactory.getSerializer(request.getSerializeType());
- Method declaredMethod = proxyClass.getDeclaredMethod(methodName, argTypes);
+ Method declaredMethod = ReflectCache.getOverloadMethodCache(key, methodName, request.getArgTypesList()
+ .toArray(new String[0]));
Object[] invokeArgs = getInvokeArgs(request, argTypes, serializer);
// fill sofaRequest
diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java
index 6046912f4..6d3dcbf14 100644
--- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java
+++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java
@@ -16,7 +16,9 @@
*/
package com.alipay.sofa.rpc.server.triple;
+import com.alipay.sofa.rpc.common.cache.ReflectCache;
import com.alipay.sofa.rpc.common.struct.NamedThreadFactory;
+import com.alipay.sofa.rpc.config.ConfigUniqueNameGenerator;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;
import com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException;
@@ -267,7 +269,7 @@ public void registerProcessor(ProviderConfig providerConfig, Invoker instance) {
BindableService bindableService = (BindableService) providerConfig.getRef();
serviceDef = bindableService.bindService();
} else {
- GenericServiceImpl genericService = new GenericServiceImpl(uniqueIdInvoker, providerConfig.getProxyClass());
+ GenericServiceImpl genericService = new GenericServiceImpl(uniqueIdInvoker, providerConfig);
genericService.setProxiedImpl(genericService);
serviceDef = buildSofaServiceDef(genericService, providerConfig);
}
@@ -380,6 +382,7 @@ protected List buildInterceptorChain(ServerServiceDefin
@Override
public void unRegisterProcessor(ProviderConfig providerConfig, boolean closeIfNoEntry) {
this.lock.lock();
+ cleanReflectCache(providerConfig);
try {
ServerServiceDefinition serverServiceDefinition = this.serviceInfo.get(providerConfig);
UniqueIdInvoker uniqueIdInvoker = this.invokerMap.get(providerConfig.getInterfaceId());
@@ -403,6 +406,14 @@ public void unRegisterProcessor(ProviderConfig providerConfig, boolean closeIfNo
}
}
+ public void cleanReflectCache(ProviderConfig providerConfig) {
+ String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig);
+ ReflectCache.unRegisterServiceClassLoader(key);
+ ReflectCache.invalidateMethodCache(key);
+ ReflectCache.invalidateMethodSigsCache(key);
+ ReflectCache.invalidateOverloadMethodCache(key);
+ }
+
@Override
public void destroy() {
stop();
diff --git a/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java b/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java
index dda7674aa..b5b1b046c 100644
--- a/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java
+++ b/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java
@@ -19,6 +19,7 @@
import com.alipay.sofa.rpc.codec.Serializer;
import com.alipay.sofa.rpc.codec.SerializerFactory;
import com.alipay.sofa.rpc.codec.sofahessian.SofaHessianSerializer;
+import com.alipay.sofa.rpc.config.ConfigUniqueNameGenerator;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.core.request.SofaRequest;
import com.alipay.sofa.rpc.filter.ProviderInvoker;
@@ -46,18 +47,22 @@ public class GenericServiceImplTest {
private GenericServiceImpl genericService;
private MockStreamObserver responseObserver;
+ private ProviderConfig providerConfig;
+
public GenericServiceImplTest(){
- ProviderConfig providerConfig = new ProviderConfig<>();
+ providerConfig = new ProviderConfig<>();
providerConfig.setRef(new HelloServiceImpl());
- providerConfig.setProxyClass(HelloService.class);
+ providerConfig.setInterfaceId(HelloService.class.getName());
ProviderInvoker invoker = new ProviderInvoker<>(providerConfig);
- genericService = new GenericServiceImpl(invoker,providerConfig.getProxyClass());
+ genericService = new GenericServiceImpl(invoker,providerConfig);
responseObserver = new MockStreamObserver<>();
}
@Test
public void testPrimitiveType() throws NoSuchMethodException {
// test return primitive type
+ Assert.assertEquals("com.alipay.sofa.rpc.server.triple.HelloService:1.0",
+ ConfigUniqueNameGenerator.getUniqueName(providerConfig));
String methodName = "testPrimitiveType";
Method method = HelloService.class.getDeclaredMethod(methodName, long.class);
diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java
new file mode 100644
index 000000000..69982a471
--- /dev/null
+++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alipay.sofa.rpc.test.triple;
+
+/**
+ * @author zhaowang
+ * @version : SampleService.java, v 0.1 2022年06月17日 3:33 PM zhaowang
+ */
+public interface SampleService {
+
+ String hello(String name);
+
+}
diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java
index 6870dae2b..93bb26758 100644
--- a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java
+++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java
@@ -242,12 +242,6 @@ public void testSyncTimeout() {
Assert.assertTrue(exp);
}
- public interface SampleService {
-
- String hello(String name);
-
- }
-
@BeforeClass
public static void adBeforeClass() {
RpcRunningState.setUnitTestMode(true);