Fix reflection exceptions caused by having identically named fallback/blockHandler with different parameter types (#3395)
This commit is contained in:
parent
bb813ddff3
commit
568e2df296
|
|
@ -33,7 +33,7 @@ public class DemoController {
|
|||
private TestService service;
|
||||
|
||||
@GetMapping("/foo")
|
||||
public String apiFoo(@RequestParam(required = false) Long t) throws Exception {
|
||||
public String apiFoo(@RequestParam(required = false) Long t) {
|
||||
if (t == null) {
|
||||
t = System.currentTimeMillis();
|
||||
}
|
||||
|
|
@ -41,6 +41,12 @@ public class DemoController {
|
|||
return service.hello(t);
|
||||
}
|
||||
|
||||
@GetMapping("/bar")
|
||||
public String apiBar(@RequestParam(required = false) String t) {
|
||||
service.test();
|
||||
return service.hello(t);
|
||||
}
|
||||
|
||||
@GetMapping("/baz/{name}")
|
||||
public String apiBaz(@PathVariable("name") String name) {
|
||||
return service.helloAnother(name);
|
||||
|
|
|
|||
|
|
@ -24,5 +24,7 @@ public interface TestService {
|
|||
|
||||
String hello(long s);
|
||||
|
||||
String hello(String s);
|
||||
|
||||
String helloAnother(String name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
package com.alibaba.csp.sentinel.demo.annotation.aop.service;
|
||||
|
||||
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
|
|
@ -41,6 +39,15 @@ public class TestServiceImpl implements TestService {
|
|||
return String.format("Hello at %d", s);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SentinelResource(value = "helloStr", fallback = "helloFallback")
|
||||
public String hello(String s) {
|
||||
if (s == null || s.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("unknown");
|
||||
}
|
||||
return String.format("Hello, %s", s);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SentinelResource(value = "helloAnother", defaultFallback = "defaultFallback",
|
||||
exceptionsToIgnore = {IllegalStateException.class})
|
||||
|
|
@ -60,6 +67,12 @@ public class TestServiceImpl implements TestService {
|
|||
return "Oops, error occurred at " + s;
|
||||
}
|
||||
|
||||
private String helloFallback(String ignored, Throwable e) {
|
||||
// Do some log here.
|
||||
e.printStackTrace();
|
||||
return "Hello, stranger";
|
||||
}
|
||||
|
||||
public String defaultFallback() {
|
||||
System.out.println("Go to default fallback");
|
||||
return "default_fallback";
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import java.util.Arrays;
|
|||
*
|
||||
* @author Eric Zhao
|
||||
* @author zhaoyuguang
|
||||
* @author dowenliu-xyz(hawkdowen@hotmail.com)
|
||||
*/
|
||||
public abstract class AbstractSentinelAspectSupport {
|
||||
|
||||
|
|
@ -177,12 +178,13 @@ public abstract class AbstractSentinelAspectSupport {
|
|||
}
|
||||
boolean mustStatic = locationClass != null && locationClass.length >= 1;
|
||||
Class<?> clazz = mustStatic ? locationClass[0] : pjp.getTarget().getClass();
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName);
|
||||
Method originMethod = resolveMethod(pjp);
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName, originMethod.getParameterTypes());
|
||||
if (m == null) {
|
||||
// First time, resolve the fallback.
|
||||
Method method = resolveFallbackInternal(pjp, fallbackName, clazz, mustStatic);
|
||||
Method method = resolveFallbackInternal(originMethod, fallbackName, clazz, mustStatic);
|
||||
// Cache the method instance.
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, method);
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, originMethod.getParameterTypes(), method);
|
||||
return method;
|
||||
}
|
||||
if (!m.isPresent()) {
|
||||
|
|
@ -232,9 +234,7 @@ public abstract class AbstractSentinelAspectSupport {
|
|||
return m.getMethod();
|
||||
}
|
||||
|
||||
private Method resolveFallbackInternal(ProceedingJoinPoint pjp, /*@NonNull*/ String name, Class<?> clazz,
|
||||
boolean mustStatic) {
|
||||
Method originMethod = resolveMethod(pjp);
|
||||
private Method resolveFallbackInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
|
||||
// Fallback function allows two kinds of parameter list.
|
||||
Class<?>[] defaultParamTypes = originMethod.getParameterTypes();
|
||||
Class<?>[] paramTypesWithException = Arrays.copyOf(defaultParamTypes, defaultParamTypes.length + 1);
|
||||
|
|
@ -261,12 +261,13 @@ public abstract class AbstractSentinelAspectSupport {
|
|||
// By default current class.
|
||||
clazz = pjp.getTarget().getClass();
|
||||
}
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name);
|
||||
Method originMethod = resolveMethod(pjp);
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name, originMethod.getParameterTypes());
|
||||
if (m == null) {
|
||||
// First time, resolve the block handler.
|
||||
Method method = resolveBlockHandlerInternal(pjp, name, clazz, mustStatic);
|
||||
Method method = resolveBlockHandlerInternal(originMethod, name, clazz, mustStatic);
|
||||
// Cache the method instance.
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, method);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, originMethod.getParameterTypes(), method);
|
||||
return method;
|
||||
}
|
||||
if (!m.isPresent()) {
|
||||
|
|
@ -275,9 +276,7 @@ public abstract class AbstractSentinelAspectSupport {
|
|||
return m.getMethod();
|
||||
}
|
||||
|
||||
private Method resolveBlockHandlerInternal(ProceedingJoinPoint pjp, /*@NonNull*/ String name, Class<?> clazz,
|
||||
boolean mustStatic) {
|
||||
Method originMethod = resolveMethod(pjp);
|
||||
private Method resolveBlockHandlerInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
|
||||
Class<?>[] originList = originMethod.getParameterTypes();
|
||||
Class<?>[] parameterTypes = Arrays.copyOf(originList, originList.length + 1);
|
||||
parameterTypes[parameterTypes.length - 1] = BlockException.class;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@
|
|||
package com.alibaba.csp.sentinel.annotation.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
|
|
@ -25,6 +27,7 @@ import com.alibaba.csp.sentinel.util.StringUtil;
|
|||
* Registry for resource configuration metadata (e.g. fallback method)
|
||||
*
|
||||
* @author Eric Zhao
|
||||
* @author dowenliu-xyz(hawkdowen@hotmail.com)
|
||||
*/
|
||||
final class ResourceMetadataRegistry {
|
||||
|
||||
|
|
@ -32,18 +35,38 @@ final class ResourceMetadataRegistry {
|
|||
private static final Map<String, MethodWrapper> DEFAULT_FALLBACK_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<String, MethodWrapper> BLOCK_HANDLER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #lookupFallback(Class, String, Class[])}
|
||||
*/
|
||||
@Deprecated
|
||||
static MethodWrapper lookupFallback(Class<?> clazz, String name) {
|
||||
return FALLBACK_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
||||
static MethodWrapper lookupFallback(Class<?> clazz, String name, Class<?>[] parameterTypes) {
|
||||
return FALLBACK_MAP.get(getKey(clazz, name, parameterTypes));
|
||||
}
|
||||
|
||||
static MethodWrapper lookupDefaultFallback(Class<?> clazz, String name) {
|
||||
return DEFAULT_FALLBACK_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #lookupBlockHandler(Class, String, Class[])}
|
||||
*/
|
||||
@Deprecated
|
||||
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name) {
|
||||
return BLOCK_HANDLER_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
||||
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name, Class<?>[] parameterTypes) {
|
||||
return BLOCK_HANDLER_MAP.get(getKey(clazz, name, parameterTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #updateFallbackFor(Class, String, Class[], Method)}
|
||||
*/
|
||||
@Deprecated
|
||||
static void updateFallbackFor(Class<?> clazz, String name, Method method) {
|
||||
if (clazz == null || StringUtil.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
|
|
@ -51,6 +74,13 @@ final class ResourceMetadataRegistry {
|
|||
FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
|
||||
}
|
||||
|
||||
static void updateFallbackFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes, Method handlerMethod) {
|
||||
if (clazz == null || StringUtil.isBlank(handlerName)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
}
|
||||
FALLBACK_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
|
||||
}
|
||||
|
||||
static void updateDefaultFallbackFor(Class<?> clazz, String name, Method method) {
|
||||
if (clazz == null || StringUtil.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
|
|
@ -58,6 +88,11 @@ final class ResourceMetadataRegistry {
|
|||
DEFAULT_FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #updateBlockHandlerFor(Class, String, Class[], Method)}
|
||||
*/
|
||||
@Deprecated
|
||||
static void updateBlockHandlerFor(Class<?> clazz, String name, Method method) {
|
||||
if (clazz == null || StringUtil.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
|
|
@ -65,10 +100,27 @@ final class ResourceMetadataRegistry {
|
|||
BLOCK_HANDLER_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
|
||||
}
|
||||
|
||||
static void updateBlockHandlerFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes,
|
||||
Method handlerMethod) {
|
||||
if (clazz == null || StringUtil.isBlank(handlerName)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
}
|
||||
BLOCK_HANDLER_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
|
||||
}
|
||||
|
||||
private static String getKey(Class<?> clazz, String name) {
|
||||
return String.format("%s:%s", clazz.getCanonicalName(), name);
|
||||
}
|
||||
|
||||
private static String getKey(Class<?> clazz, String name, Class<?>[] parameterTypes) {
|
||||
return String.format(
|
||||
"%s:%s;%s",
|
||||
clazz.getCanonicalName(),
|
||||
name,
|
||||
Arrays.stream(parameterTypes).map(Class::getCanonicalName).collect(Collectors.joining(","))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for internal test.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
* @author dowenliu-xyz(hawkdowen@hotmail.com)
|
||||
*/
|
||||
public class ResourceMetadataRegistryTest {
|
||||
|
||||
|
|
@ -45,14 +46,15 @@ public class ResourceMetadataRegistryTest {
|
|||
public void testUpdateThenLookupFallback() {
|
||||
Class<?> clazz = FooService.class;
|
||||
String methodName = "someMethodFallback";
|
||||
Class<?>[] parameterTypes = new Class<?>[]{String.class, int.class};
|
||||
Method method = clazz.getMethods()[0];
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName)).isNull();
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes)).isNull();
|
||||
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName).isPresent()).isFalse();
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes).isPresent()).isFalse();
|
||||
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName);
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes);
|
||||
assertThat(wrapper.isPresent()).isTrue();
|
||||
assertThat(wrapper.getMethod()).isSameAs(method);
|
||||
}
|
||||
|
|
@ -61,25 +63,26 @@ public class ResourceMetadataRegistryTest {
|
|||
public void testUpdateThenLookupBlockHandler() {
|
||||
Class<?> clazz = FooService.class;
|
||||
String methodName = "someMethodBlockHand;er";
|
||||
Class<?>[] parameterTypes = new Class<?>[]{String.class, int.class};
|
||||
Method method = clazz.getMethods()[1];
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName)).isNull();
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes)).isNull();
|
||||
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName).isPresent()).isFalse();
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes).isPresent()).isFalse();
|
||||
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes);
|
||||
assertThat(wrapper.isPresent()).isTrue();
|
||||
assertThat(wrapper.getMethod()).isSameAs(method);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testUpdateBlockHandlerBadArgument() {
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", String.class.getMethods()[0]);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", new Class<?>[]{}, String.class.getMethods()[0]);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testUpdateFallbackBadArgument() {
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", String.class.getMethods()[0]);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", new Class[0], String.class.getMethods()[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import java.util.Arrays;
|
|||
*
|
||||
* @author Eric Zhao
|
||||
* @author seasidesky
|
||||
* @author dowenliu-xyz(hawkdowen@hotmail.com)
|
||||
*/
|
||||
public abstract class AbstractSentinelInterceptorSupport {
|
||||
|
||||
|
|
@ -170,12 +171,13 @@ public abstract class AbstractSentinelInterceptorSupport {
|
|||
}
|
||||
boolean mustStatic = locationClass != null && locationClass.length >= 1;
|
||||
Class<?> clazz = mustStatic ? locationClass[0] : ctx.getTarget().getClass();
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName);
|
||||
Method originMethod = resolveMethod(ctx);
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName, originMethod.getParameterTypes());
|
||||
if (m == null) {
|
||||
// First time, resolve the fallback.
|
||||
Method method = resolveFallbackInternal(ctx, fallbackName, clazz, mustStatic);
|
||||
Method method = resolveFallbackInternal(originMethod, fallbackName, clazz, mustStatic);
|
||||
// Cache the method instance.
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, method);
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, originMethod.getParameterTypes(), method);
|
||||
return method;
|
||||
}
|
||||
if (!m.isPresent()) {
|
||||
|
|
@ -225,9 +227,7 @@ public abstract class AbstractSentinelInterceptorSupport {
|
|||
return m.getMethod();
|
||||
}
|
||||
|
||||
private Method resolveFallbackInternal(InvocationContext ctx, /*@NonNull*/ String name, Class<?> clazz,
|
||||
boolean mustStatic) {
|
||||
Method originMethod = resolveMethod(ctx);
|
||||
private Method resolveFallbackInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
|
||||
// Fallback function allows two kinds of parameter list.
|
||||
Class<?>[] defaultParamTypes = originMethod.getParameterTypes();
|
||||
Class<?>[] paramTypesWithException = Arrays.copyOf(defaultParamTypes, defaultParamTypes.length + 1);
|
||||
|
|
@ -254,12 +254,13 @@ public abstract class AbstractSentinelInterceptorSupport {
|
|||
// By default current class.
|
||||
clazz = ctx.getTarget().getClass();
|
||||
}
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name);
|
||||
Method originMethod = resolveMethod(ctx);
|
||||
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name, originMethod.getParameterTypes());
|
||||
if (m == null) {
|
||||
// First time, resolve the block handler.
|
||||
Method method = resolveBlockHandlerInternal(ctx, name, clazz, mustStatic);
|
||||
Method method = resolveBlockHandlerInternal(originMethod, name, clazz, mustStatic);
|
||||
// Cache the method instance.
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, method);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, originMethod.getParameterTypes(), method);
|
||||
return method;
|
||||
}
|
||||
if (!m.isPresent()) {
|
||||
|
|
@ -268,9 +269,7 @@ public abstract class AbstractSentinelInterceptorSupport {
|
|||
return m.getMethod();
|
||||
}
|
||||
|
||||
private Method resolveBlockHandlerInternal(InvocationContext ctx, /*@NonNull*/ String name, Class<?> clazz,
|
||||
boolean mustStatic) {
|
||||
Method originMethod = resolveMethod(ctx);
|
||||
private Method resolveBlockHandlerInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
|
||||
Class<?>[] originList = originMethod.getParameterTypes();
|
||||
Class<?>[] parameterTypes = Arrays.copyOf(originList, originList.length + 1);
|
||||
parameterTypes[parameterTypes.length - 1] = BlockException.class;
|
||||
|
|
|
|||
|
|
@ -18,13 +18,16 @@ package com.alibaba.csp.sentinel.annotation.cdi.interceptor;
|
|||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Registry for resource configuration metadata (e.g. fallback method)
|
||||
*
|
||||
* @author Eric Zhao
|
||||
* @author dowenliu-xyz(hawkdowen@hotmail.com)
|
||||
*/
|
||||
final class ResourceMetadataRegistry {
|
||||
|
||||
|
|
@ -32,18 +35,38 @@ final class ResourceMetadataRegistry {
|
|||
private static final Map<String, MethodWrapper> DEFAULT_FALLBACK_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<String, MethodWrapper> BLOCK_HANDLER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #lookupFallback(Class, String, Class[])}
|
||||
*/
|
||||
@Deprecated
|
||||
static MethodWrapper lookupFallback(Class<?> clazz, String name) {
|
||||
return FALLBACK_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
||||
static MethodWrapper lookupFallback(Class<?> clazz, String name, Class<?>[] parameterTypes) {
|
||||
return FALLBACK_MAP.get(getKey(clazz, name, parameterTypes));
|
||||
}
|
||||
|
||||
static MethodWrapper lookupDefaultFallback(Class<?> clazz, String name) {
|
||||
return DEFAULT_FALLBACK_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #lookupBlockHandler(Class, String, Class[])}
|
||||
*/
|
||||
@Deprecated
|
||||
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name) {
|
||||
return BLOCK_HANDLER_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
||||
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name, Class<?>[] parameterTypes) {
|
||||
return BLOCK_HANDLER_MAP.get(getKey(clazz, name, parameterTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #updateFallbackFor(Class, String, Class[], Method)}
|
||||
*/
|
||||
@Deprecated
|
||||
static void updateFallbackFor(Class<?> clazz, String name, Method method) {
|
||||
if (clazz == null || StringUtil.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
|
|
@ -51,6 +74,13 @@ final class ResourceMetadataRegistry {
|
|||
FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
|
||||
}
|
||||
|
||||
static void updateFallbackFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes, Method handlerMethod) {
|
||||
if (clazz == null || StringUtil.isBlank(handlerName)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
}
|
||||
FALLBACK_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
|
||||
}
|
||||
|
||||
static void updateDefaultFallbackFor(Class<?> clazz, String name, Method method) {
|
||||
if (clazz == null || StringUtil.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
|
|
@ -58,6 +88,11 @@ final class ResourceMetadataRegistry {
|
|||
DEFAULT_FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #updateBlockHandlerFor(Class, String, Class[], Method)}
|
||||
*/
|
||||
@Deprecated
|
||||
static void updateBlockHandlerFor(Class<?> clazz, String name, Method method) {
|
||||
if (clazz == null || StringUtil.isBlank(name)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
|
|
@ -65,10 +100,27 @@ final class ResourceMetadataRegistry {
|
|||
BLOCK_HANDLER_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
|
||||
}
|
||||
|
||||
static void updateBlockHandlerFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes,
|
||||
Method handlerMethod) {
|
||||
if (clazz == null || StringUtil.isBlank(handlerName)) {
|
||||
throw new IllegalArgumentException("Bad argument");
|
||||
}
|
||||
BLOCK_HANDLER_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
|
||||
}
|
||||
|
||||
private static String getKey(Class<?> clazz, String name) {
|
||||
return String.format("%s:%s", clazz.getCanonicalName(), name);
|
||||
}
|
||||
|
||||
private static String getKey(Class<?> clazz, String name, Class<?>[] parameterTypes) {
|
||||
return String.format(
|
||||
"%s:%s;%s",
|
||||
clazz.getCanonicalName(),
|
||||
name,
|
||||
Arrays.stream(parameterTypes).map(Class::getCanonicalName).collect(Collectors.joining(","))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only for internal test.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
* @author dowenliu-xyz(hawkdowen@hotmail.com)
|
||||
*/
|
||||
public class ResourceMetadataRegistryTest {
|
||||
|
||||
|
|
@ -46,14 +47,15 @@ public class ResourceMetadataRegistryTest {
|
|||
public void testUpdateThenLookupFallback() {
|
||||
Class<?> clazz = FooService.class;
|
||||
String methodName = "someMethodFallback";
|
||||
Class<?>[] parameterTypes = new Class<?>[] {String.class};
|
||||
Method method = clazz.getMethods()[0];
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName)).isNull();
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes)).isNull();
|
||||
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName).isPresent()).isFalse();
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes).isPresent()).isFalse();
|
||||
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName);
|
||||
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes);
|
||||
assertThat(wrapper.isPresent()).isTrue();
|
||||
assertThat(wrapper.getMethod()).isSameAs(method);
|
||||
}
|
||||
|
|
@ -62,25 +64,26 @@ public class ResourceMetadataRegistryTest {
|
|||
public void testUpdateThenLookupBlockHandler() {
|
||||
Class<?> clazz = FooService.class;
|
||||
String methodName = "someMethodBlockHand;er";
|
||||
Class<?>[] parameterTypes = new Class<?>[] {String.class};
|
||||
Method method = clazz.getMethods()[1];
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName)).isNull();
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes)).isNull();
|
||||
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName).isPresent()).isFalse();
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, null);
|
||||
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes).isPresent()).isFalse();
|
||||
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, method);
|
||||
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes);
|
||||
assertThat(wrapper.isPresent()).isTrue();
|
||||
assertThat(wrapper.getMethod()).isSameAs(method);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testUpdateBlockHandlerBadArgument() {
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", String.class.getMethods()[0]);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", new Class[0], String.class.getMethods()[0]);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testUpdateFallbackBadArgument() {
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", String.class.getMethods()[0]);
|
||||
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", new Class[0], String.class.getMethods()[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue