Revise contribution

See gh-25316
This commit is contained in:
Sam Brannen 2023-03-14 17:28:12 +01:00
parent 97b5af8a55
commit 1de36abc07
2 changed files with 32 additions and 21 deletions

View File

@ -19,7 +19,13 @@ package org.springframework.expression.spel.support;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.core.BridgeMethodResolver; import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
@ -42,6 +48,7 @@ import org.springframework.lang.Nullable;
* @author Andy Clement * @author Andy Clement
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams * @author Chris Beams
* @author Sam Brannen
* @since 3.0 * @since 3.0
* @see StandardEvaluationContext#addMethodResolver(MethodResolver) * @see StandardEvaluationContext#addMethodResolver(MethodResolver)
*/ */
@ -238,6 +245,12 @@ public class ReflectiveMethodResolver implements MethodResolver {
} }
} }
} }
// Ensure methods defined in java.lang.Object are exposed for JDK proxies.
for (Method method : getMethods(Object.class)) {
if (isCandidateForInvocation(method, type)) {
result.add(method);
}
}
return result; return result;
} }
else { else {
@ -260,13 +273,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
* @since 3.1.1 * @since 3.1.1
*/ */
protected Method[] getMethods(Class<?> type) { protected Method[] getMethods(Class<?> type) {
Set<Method> methods=new HashSet<>(); return type.getMethods();
methods.addAll(Arrays.asList(type.getMethods()));
//Add all methods of Object to have methods like toString on Proxy-Objects
methods.addAll(Arrays.asList(Object.class.getMethods()));
Method[] methods1 = methods.toArray(new Method[0]);
return methods1;
} }
/** /**

View File

@ -18,7 +18,6 @@ package org.springframework.expression.spel.support;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.ArrayList; import java.util.ArrayList;
@ -27,12 +26,16 @@ import java.util.List;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.*; import org.springframework.expression.EvaluationContext;
import org.springframework.expression.MethodExecutor;
import org.springframework.expression.MethodResolver;
import org.springframework.expression.ParseException;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.AbstractExpressionTests; import org.springframework.expression.spel.AbstractExpressionTests;
import org.springframework.expression.spel.SpelUtilities; import org.springframework.expression.spel.SpelUtilities;
import org.springframework.expression.spel.standard.SpelExpression; import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.support.ReflectionHelper.ArgumentsMatchKind; import org.springframework.expression.spel.support.ReflectionHelper.ArgumentsMatchKind;
import org.springframework.util.Assert;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -365,17 +368,18 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
} }
@Test @Test
void testReflectiveMethodResolver() throws AccessException { void reflectiveMethodResolverForJdkProxies() throws Exception {
MethodResolver resolver=new ReflectiveMethodResolver(); Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] { Runnable.class }, (p, m, args) -> null);
MethodResolver resolver = new ReflectiveMethodResolver();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
Object obj= Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[]{Runnable.class}, new InvocationHandler() {
@Override MethodExecutor bogus = resolver.resolve(evaluationContext, proxy, "bogus", List.of());
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { assertThat(bogus).as("MethodExecutor for bogus()").isNull();
return null; MethodExecutor toString = resolver.resolve(evaluationContext, proxy, "toString", List.of());
} assertThat(toString).as("MethodExecutor for toString()").isNotNull();
}); MethodExecutor hashCode = resolver.resolve(evaluationContext, proxy, "hashCode", List.of());
MethodExecutor mexec=resolver.resolve(evaluationContext,obj,"toString",new ArrayList<>()); assertThat(hashCode).as("MethodExecutor for hashCode()").isNotNull();
Assert.notNull(mexec,"MethodExecutor should not be empty.");
} }
/** /**