MethodParameter supports Java 8 Executable/Parameter and validates parameter indexes

Also, equals insists on the same class now, differentiating from SynthesizingMethodParameter.

Issue: SPR-14055
Issue: SPR-13456
Issue: SPR-14438
This commit is contained in:
Juergen Hoeller
2016-07-07 00:37:52 +02:00
parent da9c24c41e
commit 39e3f2ebf6
9 changed files with 313 additions and 87 deletions

View File

@@ -18,7 +18,7 @@ package org.springframework.beans.factory.support;
import java.beans.ConstructorProperties;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
@@ -506,7 +506,7 @@ class ConstructorResolver {
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterTypes().length &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
@@ -662,7 +662,7 @@ class ConstructorResolver {
*/
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Object methodOrCtor,
BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Executable executable,
boolean autowiring) throws UnsatisfiedDependencyException {
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
@@ -699,7 +699,7 @@ class ConstructorResolver {
ConstructorArgumentValues.ValueHolder sourceHolder =
(ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
Object sourceValue = sourceHolder.getValue();
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
// TODO re-enable once race condition has been found (SPR-7423)
@@ -727,7 +727,7 @@ class ConstructorResolver {
args.rawArguments[paramIndex] = originalValue;
}
else {
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
@@ -755,7 +755,7 @@ class ConstructorResolver {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (this.beanFactory.logger.isDebugEnabled()) {
this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (methodOrCtor instanceof Constructor ? "constructor" : "factory method") +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
@@ -767,10 +767,9 @@ class ConstructorResolver {
* Resolve the prepared arguments stored in the given bean definition.
*/
private Object[] resolvePreparedArguments(
String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {
String beanName, RootBeanDefinition mbd, BeanWrapper bw, Executable executable, Object[] argsToResolve) {
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
Class<?>[] paramTypes = executable.getParameterTypes();
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);
BeanDefinitionValueResolver valueResolver =
@@ -778,8 +777,8 @@ class ConstructorResolver {
Object[] resolvedArgs = new Object[argsToResolve.length];
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
Object argValue = argsToResolve[argIndex];
MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, argIndex);
GenericTypeResolver.resolveParameterType(methodParam, methodOrCtor.getDeclaringClass());
MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
GenericTypeResolver.resolveParameterType(methodParam, executable.getDeclaringClass());
if (argValue instanceof AutowiredArgumentMarker) {
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
}