提交 7553b76f 编写于 作者: J Juergen Hoeller

SpEL method invocations prefer method with fewest parameters (e.g. no-arg over vararg; SPR-7633)

上级 d78eda8a
......@@ -17,17 +17,19 @@
package org.springframework.expression.spel.support;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.AccessException;
import org.springframework.expression.ConstructorExecutor;
import org.springframework.expression.ConstructorResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypeConverter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.MethodParameter;
/**
* A constructor resolver that uses reflection to locate the constructor that should be invoked
......@@ -49,13 +51,24 @@ public class ReflectiveConstructorResolver implements ConstructorResolver {
*/
public ConstructorExecutor resolve(EvaluationContext context, String typename, List<TypeDescriptor> argumentTypes)
throws AccessException {
try {
TypeConverter typeConverter = context.getTypeConverter();
Class<?> type = context.getTypeLocator().findType(typename);
Constructor[] ctors = type.getConstructors();
Arrays.sort(ctors, new Comparator<Constructor>() {
public int compare(Constructor c1, Constructor c2) {
int c1pl = c1.getParameterTypes().length;
int c2pl = c2.getParameterTypes().length;
return (new Integer(c1pl)).compareTo(c2pl);
}
});
Constructor closeMatch = null;
int[] argsToConvert = null;
Constructor matchRequiringConversion = null;
for (Constructor ctor : ctors) {
Class[] paramTypes = ctor.getParameterTypes();
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
......
......@@ -18,6 +18,8 @@ package org.springframework.expression.spel.support;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -33,11 +35,13 @@ import org.springframework.expression.MethodResolver;
import org.springframework.expression.TypeConverter;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.SpelMessage;
import org.springframework.util.CollectionUtils;
/**
* A method resolver that uses reflection to locate the method that should be invoked.
*
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
public class ReflectiveMethodResolver implements MethodResolver {
......@@ -58,31 +62,41 @@ public class ReflectiveMethodResolver implements MethodResolver {
*/
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name,
List<TypeDescriptor> argumentTypes) throws AccessException {
try {
TypeConverter typeConverter = context.getTypeConverter();
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
Method[] methods = type.getMethods();
// If a filter is registered for this type, call it
MethodFilter methodfilter = (filters==null?null:filters.get(type));
if (methodfilter!=null) {
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
if (filter != null) {
List<Method> methodsForFiltering = new ArrayList<Method>();
for (Method method: methods) {
methodsForFiltering.add(method);
}
List<Method> methodsFiltered = methodfilter.filter(methodsForFiltering);
if (methodsFiltered == null || methodsFiltered.size()==0) {
List<Method> methodsFiltered = filter.filter(methodsForFiltering);
if (CollectionUtils.isEmpty(methodsFiltered)) {
methods = NO_METHODS;
}
else {
methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]);
}
}
Arrays.sort(methods, new Comparator<Method>() {
public int compare(Method m1, Method m2) {
int m1pl = m1.getParameterTypes().length;
int m2pl = m2.getParameterTypes().length;
return (new Integer(m1pl)).compareTo(m2pl);
}
});
Method closeMatch = null;
int[] argsToConvert = null;
boolean multipleOptions = false;
Method matchRequiringConversion = null;
boolean multipleOptions = false;
for (Method method : methods) {
if (method.isBridge()) {
continue;
......@@ -139,7 +153,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
public void registerMethodFilter(Class<?> type, MethodFilter filter) {
if (this.filters == null) {
this.filters = new HashMap<Class<?>,MethodFilter>();
this.filters = new HashMap<Class<?>, MethodFilter>();
}
if (filter == null) {
this.filters.remove(type);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册