Removed logging from GenericTypeResolver's resolveReturnTypeForGenericMethod
GenericTypeResolver is very low-level and quite a hotspot, so let's not do any logging there and rather use the debugger instead.
This commit is contained in:
parent
7d798acd35
commit
a694db2933
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,11 +26,7 @@ import java.lang.reflect.WildcardType;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,12 +43,11 @@ import org.springframework.util.ConcurrentReferenceHashMap;
|
||||||
*/
|
*/
|
||||||
public abstract class GenericTypeResolver {
|
public abstract class GenericTypeResolver {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(GenericTypeResolver.class);
|
|
||||||
|
|
||||||
/** Cache from Class to TypeVariable Map */
|
/** Cache from Class to TypeVariable Map */
|
||||||
private static final Map<Class, Map<TypeVariable, Type>> typeVariableCache =
|
private static final Map<Class, Map<TypeVariable, Type>> typeVariableCache =
|
||||||
new ConcurrentReferenceHashMap<Class, Map<TypeVariable,Type>>();
|
new ConcurrentReferenceHashMap<Class, Map<TypeVariable,Type>>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the target type for the given parameter specification.
|
* Determine the target type for the given parameter specification.
|
||||||
* @param methodParam the method parameter specification
|
* @param methodParam the method parameter specification
|
||||||
|
@ -93,7 +88,6 @@ public abstract class GenericTypeResolver {
|
||||||
/**
|
/**
|
||||||
* Determine the target type for the generic return type of the given method,
|
* Determine the target type for the generic return type of the given method,
|
||||||
* where formal type variables are declared on the given class.
|
* where formal type variables are declared on the given class.
|
||||||
*
|
|
||||||
* @param method the method to introspect
|
* @param method the method to introspect
|
||||||
* @param clazz the class to resolve type variables against
|
* @param clazz the class to resolve type variables against
|
||||||
* @return the corresponding generic parameter or return type
|
* @return the corresponding generic parameter or return type
|
||||||
|
@ -112,15 +106,12 @@ public abstract class GenericTypeResolver {
|
||||||
* Determine the target type for the generic return type of the given
|
* Determine the target type for the generic return type of the given
|
||||||
* <em>generic method</em>, where formal type variables are declared on
|
* <em>generic method</em>, where formal type variables are declared on
|
||||||
* the given method itself.
|
* the given method itself.
|
||||||
*
|
|
||||||
* <p>For example, given a factory method with the following signature,
|
* <p>For example, given a factory method with the following signature,
|
||||||
* if {@code resolveReturnTypeForGenericMethod()} is invoked with the reflected
|
* if {@code resolveReturnTypeForGenericMethod()} is invoked with the reflected
|
||||||
* method for {@code creatProxy()} and an {@code Object[]} array containing
|
* method for {@code creatProxy()} and an {@code Object[]} array containing
|
||||||
* {@code MyService.class}, {@code resolveReturnTypeForGenericMethod()} will
|
* {@code MyService.class}, {@code resolveReturnTypeForGenericMethod()} will
|
||||||
* infer that the target return type is {@code MyService}.
|
* infer that the target return type is {@code MyService}.
|
||||||
*
|
|
||||||
* <pre>{@code public static <T> T createProxy(Class<T> clazz)}</pre>
|
* <pre>{@code public static <T> T createProxy(Class<T> clazz)}</pre>
|
||||||
*
|
|
||||||
* <h4>Possible Return Values</h4>
|
* <h4>Possible Return Values</h4>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>the target return type, if it can be inferred</li>
|
* <li>the target return type, if it can be inferred</li>
|
||||||
|
@ -134,27 +125,20 @@ public abstract class GenericTypeResolver {
|
||||||
* Method#getGenericParameterTypes() formal argument list} for the given
|
* Method#getGenericParameterTypes() formal argument list} for the given
|
||||||
* method</li>
|
* method</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
|
||||||
* @param method the method to introspect, never {@code null}
|
* @param method the method to introspect, never {@code null}
|
||||||
* @param args the arguments that will be supplied to the method when it is
|
* @param args the arguments that will be supplied to the method when it is
|
||||||
* invoked, never {@code null}
|
* invoked, never {@code null}
|
||||||
* @return the resolved target return type, the standard return type, or
|
* @return the resolved target return type, the standard return type, or {@code null}
|
||||||
* {@code null}
|
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
* @see #resolveReturnType
|
* @see #resolveReturnType
|
||||||
*/
|
*/
|
||||||
public static Class<?> resolveReturnTypeForGenericMethod(Method method, Object[] args) {
|
public static Class<?> resolveReturnTypeForGenericMethod(Method method, Object[] args) {
|
||||||
Assert.notNull(method, "method must not be null");
|
Assert.notNull(method, "Method must not be null");
|
||||||
Assert.notNull(args, "args must not be null");
|
Assert.notNull(args, "Argument array must not be null");
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
TypeVariable<Method>[] declaredTypeVariables = method.getTypeParameters();
|
||||||
logger.debug(String.format("Resolving return type for [%s] with concrete method arguments [%s].",
|
Type genericReturnType = method.getGenericReturnType();
|
||||||
method.toGenericString(), ObjectUtils.nullSafeToString(args)));
|
Type[] methodArgumentTypes = method.getGenericParameterTypes();
|
||||||
}
|
|
||||||
|
|
||||||
final TypeVariable<Method>[] declaredTypeVariables = method.getTypeParameters();
|
|
||||||
final Type genericReturnType = method.getGenericReturnType();
|
|
||||||
final Type[] methodArgumentTypes = method.getGenericParameterTypes();
|
|
||||||
|
|
||||||
// No declared type variables to inspect, so just return the standard return type.
|
// No declared type variables to inspect, so just return the standard return type.
|
||||||
if (declaredTypeVariables.length == 0) {
|
if (declaredTypeVariables.length == 0) {
|
||||||
|
@ -172,11 +156,6 @@ public abstract class GenericTypeResolver {
|
||||||
boolean locallyDeclaredTypeVariableMatchesReturnType = false;
|
boolean locallyDeclaredTypeVariableMatchesReturnType = false;
|
||||||
for (TypeVariable<Method> currentTypeVariable : declaredTypeVariables) {
|
for (TypeVariable<Method> currentTypeVariable : declaredTypeVariables) {
|
||||||
if (currentTypeVariable.equals(genericReturnType)) {
|
if (currentTypeVariable.equals(genericReturnType)) {
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug(String.format(
|
|
||||||
"Found declared type variable [%s] that matches the target return type [%s].",
|
|
||||||
currentTypeVariable, genericReturnType));
|
|
||||||
}
|
|
||||||
locallyDeclaredTypeVariableMatchesReturnType = true;
|
locallyDeclaredTypeVariableMatchesReturnType = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -184,39 +163,20 @@ public abstract class GenericTypeResolver {
|
||||||
|
|
||||||
if (locallyDeclaredTypeVariableMatchesReturnType) {
|
if (locallyDeclaredTypeVariableMatchesReturnType) {
|
||||||
for (int i = 0; i < methodArgumentTypes.length; i++) {
|
for (int i = 0; i < methodArgumentTypes.length; i++) {
|
||||||
final Type currentMethodArgumentType = methodArgumentTypes[i];
|
Type currentMethodArgumentType = methodArgumentTypes[i];
|
||||||
|
|
||||||
if (currentMethodArgumentType.equals(genericReturnType)) {
|
if (currentMethodArgumentType.equals(genericReturnType)) {
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug(String.format(
|
|
||||||
"Found method argument type at index [%s] that matches the target return type.", i));
|
|
||||||
}
|
|
||||||
return args[i].getClass();
|
return args[i].getClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentMethodArgumentType instanceof ParameterizedType) {
|
if (currentMethodArgumentType instanceof ParameterizedType) {
|
||||||
ParameterizedType parameterizedType = (ParameterizedType) currentMethodArgumentType;
|
ParameterizedType parameterizedType = (ParameterizedType) currentMethodArgumentType;
|
||||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||||
|
for (Type typeArg : actualTypeArguments) {
|
||||||
for (int j = 0; j < actualTypeArguments.length; j++) {
|
|
||||||
final Type typeArg = actualTypeArguments[j];
|
|
||||||
|
|
||||||
if (typeArg.equals(genericReturnType)) {
|
if (typeArg.equals(genericReturnType)) {
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug(String.format(
|
|
||||||
"Found method argument type at index [%s] that is parameterized with a type argument that matches the target return type.",
|
|
||||||
i));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[i] instanceof Class) {
|
if (args[i] instanceof Class) {
|
||||||
return (Class<?>) args[i];
|
return (Class<?>) args[i];
|
||||||
} else {
|
}
|
||||||
// Consider adding logic to determine the class of the
|
else {
|
||||||
// J'th typeArg, if possible.
|
// Consider adding logic to determine the class of the typeArg, if possible.
|
||||||
logger.info(String.format(
|
|
||||||
"Could not determine the target type for type argument [%s] for method [%s].",
|
|
||||||
typeArg, method.toGenericString()));
|
|
||||||
|
|
||||||
// For now, just fall back...
|
// For now, just fall back...
|
||||||
return method.getReturnType();
|
return method.getReturnType();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue