diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java index badd4bc3de..91efdd2536 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java @@ -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 argumentTypes) throws AccessException { + try { TypeConverter typeConverter = context.getTypeConverter(); Class type = context.getTypeLocator().findType(typename); Constructor[] ctors = type.getConstructors(); + + Arrays.sort(ctors, new Comparator() { + 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 paramDescriptors = new ArrayList(paramTypes.length); diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java index 7b1d63297e..86bc4b3a6d 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java @@ -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 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 methodsForFiltering = new ArrayList(); for (Method method: methods) { methodsForFiltering.add(method); } - List methodsFiltered = methodfilter.filter(methodsForFiltering); - if (methodsFiltered == null || methodsFiltered.size()==0) { + List methodsFiltered = filter.filter(methodsForFiltering); + if (CollectionUtils.isEmpty(methodsFiltered)) { methods = NO_METHODS; } else { methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]); } } - + + Arrays.sort(methods, new Comparator() { + 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,MethodFilter>(); + this.filters = new HashMap, MethodFilter>(); } if (filter == null) { this.filters.remove(type);