Quellcode durchsuchen

Refactor logic of getting resource name in Sentinel annotation

- Enhance resolve name logic in MethodUtil
- Add test case for MethodUtil

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao vor 6 Jahren
Ursprung
Commit
5aad448191
4 geänderte Dateien mit 93 neuen und 32 gelöschten Zeilen
  1. +1
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slotchain/MethodResourceWrapper.java
  2. +18
    -10
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/MethodUtil.java
  3. +63
    -0
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/MethodUtilTest.java
  4. +11
    -21
      sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/SentinelResourceAspect.java

+ 1
- 1
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slotchain/MethodResourceWrapper.java Datei anzeigen

@@ -32,7 +32,7 @@ public class MethodResourceWrapper extends ResourceWrapper {


public MethodResourceWrapper(Method method, EntryType type) { public MethodResourceWrapper(Method method, EntryType type) {
this.method = method; this.method = method;
this.name = MethodUtil.getMethodName(method);
this.name = MethodUtil.resolveMethodName(method);
this.type = type; this.type = type;
} }




+ 18
- 10
sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/MethodUtil.java Datei anzeigen

@@ -16,9 +16,6 @@
package com.alibaba.csp.sentinel.util; package com.alibaba.csp.sentinel.util;


import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;


@@ -29,14 +26,20 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
public final class MethodUtil { public final class MethodUtil {


private static volatile Map<Method, String> methodNameMap = new HashMap<Method, String>();
private static final Map<Method, String> methodNameMap = new ConcurrentHashMap<Method, String>();


private static final Object LOCK = new Object(); private static final Object LOCK = new Object();


/** /**
* Parse and get the method name.
* Parse and resolve the method name, then cache to the map.
*
* @param method method instance
* @return resolved method name
*/ */
public static String getMethodName(Method method) {
public static String resolveMethodName(Method method) {
if (method == null) {
throw new IllegalArgumentException("Null method");
}
String methodName = methodNameMap.get(method); String methodName = methodNameMap.get(method);
if (methodName == null) { if (methodName == null) {
synchronized (LOCK) { synchronized (LOCK) {
@@ -52,7 +55,7 @@ public final class MethodUtil {


int paramPos = 0; int paramPos = 0;
for (Class<?> clazz : params) { for (Class<?> clazz : params) {
sb.append(clazz.getName());
sb.append(clazz.getCanonicalName());
if (++paramPos < params.length) { if (++paramPos < params.length) {
sb.append(","); sb.append(",");
} }
@@ -60,12 +63,17 @@ public final class MethodUtil {
sb.append(")"); sb.append(")");
methodName = sb.toString(); methodName = sb.toString();


HashMap<Method, String> newMap = new HashMap<Method, String>(methodNameMap);
newMap.put(method, methodName);
methodNameMap = newMap;
methodNameMap.put(method, methodName);
} }
} }
} }
return methodName; return methodName;
} }

/**
* For test.
*/
static void clearMethodMap() {
methodNameMap.clear();
}
} }

+ 63
- 0
sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/MethodUtilTest.java Datei anzeigen

@@ -0,0 +1,63 @@
package com.alibaba.csp.sentinel.util;

import java.lang.reflect.Method;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
* Test cases for {@link MethodUtil}.
*
* @author Eric Zhao
*/
public class MethodUtilTest {

@Before
public void setUp() {
MethodUtil.clearMethodMap();
}

@After
public void cleanUp() {
MethodUtil.clearMethodMap();
}

@Test
public void testResolveMethodName() {
Method fooMethod = null;
for (Method m : GoodClass.class.getMethods()) {
if (m.getName().contains("foo")) {
fooMethod = m;
break;
}
}
assertNotNull(fooMethod);
assertEquals("com.alibaba.csp.sentinel.util.MethodUtilTest$GoodClass:foo(long[],java.lang.String,java.lang.Integer[])",
MethodUtil.resolveMethodName(fooMethod));

Method bazMethod = null;
for (Method m : GoodClass.class.getMethods()) {
if (m.getName().contains("baz")) {
bazMethod = m;
break;
}
}
assertNotNull(bazMethod);
assertEquals("com.alibaba.csp.sentinel.util.MethodUtilTest$GoodClass:baz(double)",
MethodUtil.resolveMethodName(bazMethod));
}

interface GoodClass {
void foo(long[] p1, String p2, Integer[] p3);

String baz(double a);
}

@Test(expected = IllegalArgumentException.class)
public void testResolveNullMethod() {
MethodUtil.resolveMethodName(null);
}
}

+ 11
- 21
sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/SentinelResourceAspect.java Datei anzeigen

@@ -26,6 +26,7 @@ import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.util.MethodUtil;
import com.alibaba.csp.sentinel.util.StringUtil; import com.alibaba.csp.sentinel.util.StringUtil;


import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
@@ -76,28 +77,16 @@ public class SentinelResourceAspect {
ContextUtil.exit(); ContextUtil.exit();
} }
} }
private String getResourceName(String resourceName, Method method) { private String getResourceName(String resourceName, Method method) {
if(StringUtil.isNotBlank(resourceName)){
// If resource name is present in annotation, use this value.
if (StringUtil.isNotBlank(resourceName)) {
return resourceName; return resourceName;
} }
StringBuilder buf = new StringBuilder(64);
buf.append(method.getDeclaringClass().getName())
.append(":")
.append(method.getName())
.append("(");
boolean isFirst = true;
for (Class<?> clazz : method.getParameterTypes()) {
if (!isFirst) {
buf.append(",");
}
buf.append(clazz.getName());
isFirst = false;
}
buf.append(")");
return buf.toString();
// Parse name of target method.
return MethodUtil.resolveMethodName(method);
} }

private Object handleBlockException(ProceedingJoinPoint pjp, SentinelResource annotation, BlockException ex) private Object handleBlockException(ProceedingJoinPoint pjp, SentinelResource annotation, BlockException ex)
throws Exception { throws Exception {
// Execute fallback for degrading if configured. // Execute fallback for degrading if configured.
@@ -224,7 +213,8 @@ public class SentinelResourceAspect {
MethodSignature signature = (MethodSignature)joinPoint.getSignature(); MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Class<?> targetClass = joinPoint.getTarget().getClass(); Class<?> targetClass = joinPoint.getTarget().getClass();


Method method = getDeclaredMethodFor(targetClass, signature.getName(), signature.getMethod().getParameterTypes());
Method method = getDeclaredMethodFor(targetClass, signature.getName(),
signature.getMethod().getParameterTypes());
if (method == null) { if (method == null) {
throw new IllegalStateException("Cannot resolve target method: " + signature.getMethod().getName()); throw new IllegalStateException("Cannot resolve target method: " + signature.getMethod().getName());
} }
@@ -235,8 +225,8 @@ public class SentinelResourceAspect {
* Get declared method with provided name and parameterTypes in given class and its super classes. * Get declared method with provided name and parameterTypes in given class and its super classes.
* All parameters should be valid. * All parameters should be valid.
* *
* @param clazz class where the method is located
* @param name method name
* @param clazz class where the method is located
* @param name method name
* @param parameterTypes method parameter type list * @param parameterTypes method parameter type list
* @return resolved method, null if not found * @return resolved method, null if not found
*/ */


Laden…
Abbrechen
Speichern