Merge pull request #21 from aclement/spr9038
This commit is contained in:
commit
f61410705c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 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.
|
||||||
|
@ -38,27 +38,30 @@ import org.springframework.expression.spel.SpelMessage;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A method resolver that uses reflection to locate the method that should be invoked.
|
* Reflection-based {@link MethodResolver} used by default in
|
||||||
|
* {@link StandardEvaluationContext} unless explicit method resolvers have been specified.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Chris Beams
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see StandardEvaluationContext#addMethodResolver(MethodResolver)
|
||||||
*/
|
*/
|
||||||
public class ReflectiveMethodResolver implements MethodResolver {
|
public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
|
|
||||||
private static Method[] NO_METHODS = new Method[0];
|
private static Method[] NO_METHODS = new Method[0];
|
||||||
|
|
||||||
private Map<Class<?>, MethodFilter> filters = null;
|
private Map<Class<?>, MethodFilter> filters = null;
|
||||||
|
|
||||||
// Using distance will ensure a more accurate match is discovered,
|
// Using distance will ensure a more accurate match is discovered,
|
||||||
// more closely following the Java rules.
|
// more closely following the Java rules.
|
||||||
private boolean useDistance = false;
|
private boolean useDistance = false;
|
||||||
|
|
||||||
|
|
||||||
public ReflectiveMethodResolver() {
|
public ReflectiveMethodResolver() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructors allows the ReflectiveMethodResolver to be configured such that it will
|
* This constructors allows the ReflectiveMethodResolver to be configured such that it will
|
||||||
* use a distance computation to check which is the better of two close matches (when there
|
* use a distance computation to check which is the better of two close matches (when there
|
||||||
|
@ -71,7 +74,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
public ReflectiveMethodResolver(boolean useDistance) {
|
public ReflectiveMethodResolver(boolean useDistance) {
|
||||||
this.useDistance = useDistance;
|
this.useDistance = useDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locate a method on a type. There are three kinds of match that might occur:
|
* Locate a method on a type. There are three kinds of match that might occur:
|
||||||
* <ol>
|
* <ol>
|
||||||
|
@ -87,15 +90,15 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
try {
|
try {
|
||||||
TypeConverter typeConverter = context.getTypeConverter();
|
TypeConverter typeConverter = context.getTypeConverter();
|
||||||
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
|
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
|
||||||
Method[] methods = type.getMethods();
|
Method[] methods = getMethods(type);
|
||||||
|
|
||||||
// If a filter is registered for this type, call it
|
// If a filter is registered for this type, call it
|
||||||
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
|
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
List<Method> methodsForFiltering = new ArrayList<Method>();
|
List<Method> methodsForFiltering = new ArrayList<Method>();
|
||||||
for (Method method: methods) {
|
for (Method method: methods) {
|
||||||
methodsForFiltering.add(method);
|
methodsForFiltering.add(method);
|
||||||
}
|
}
|
||||||
List<Method> methodsFiltered = filter.filter(methodsForFiltering);
|
List<Method> methodsFiltered = filter.filter(methodsForFiltering);
|
||||||
if (CollectionUtils.isEmpty(methodsFiltered)) {
|
if (CollectionUtils.isEmpty(methodsFiltered)) {
|
||||||
methods = NO_METHODS;
|
methods = NO_METHODS;
|
||||||
|
@ -124,7 +127,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (method.getName().equals(name)) {
|
if (method.getName().equals(name)) {
|
||||||
Class[] paramTypes = method.getParameterTypes();
|
Class<?>[] paramTypes = method.getParameterTypes();
|
||||||
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
|
List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
|
||||||
for (int i = 0; i < paramTypes.length; i++) {
|
for (int i = 0; i < paramTypes.length; i++) {
|
||||||
paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
|
paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
|
||||||
|
@ -194,4 +197,16 @@ public class ReflectiveMethodResolver implements MethodResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the set of methods for this type. The default implementation returns the
|
||||||
|
* result of Class#getMethods for the given {@code type}, but subclasses may override
|
||||||
|
* in order to alter the results, e.g. specifying static methods declared elsewhere.
|
||||||
|
*
|
||||||
|
* @param type the class for which to return the methods
|
||||||
|
* @since 3.1.1
|
||||||
|
*/
|
||||||
|
protected Method[] getMethods(Class<?> type) {
|
||||||
|
return type.getMethods();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue