use of org.springframework.core.MethodParameter in project spring-framework by spring-projects.
the class ConstructorResolver method createArgumentArray.
/**
* Create an array of arguments to invoke a constructor or factory method,
* given the resolved constructor argument values.
*/
private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Executable executable, boolean autowiring) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
ConstructorArgumentValues.ValueHolder valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// it could match after type conversion (for example, String -> int).
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
usedValueHolders.add(valueHolder);
Object originalValue = valueHolder.getValue();
Object convertedValue;
if (valueHolder.isConverted()) {
convertedValue = valueHolder.getConvertedValue();
args.preparedArguments[paramIndex] = convertedValue;
} else {
ConstructorArgumentValues.ValueHolder sourceHolder = (ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
Object sourceValue = sourceHolder.getValue();
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
// TODO re-enable once race condition has been found (SPR-7423)
/*
if (originalValue == sourceValue || sourceValue instanceof TypedStringValue) {
// Either a converted value or still the original one: store converted value.
sourceHolder.setConvertedValue(convertedValue);
args.preparedArguments[paramIndex] = convertedValue;
}
else {
*/
args.resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
// }
} catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(valueHolder.getValue()) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
} else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?");
}
try {
Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
args.resolveNecessary = true;
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (this.beanFactory.logger.isDebugEnabled()) {
this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName + "' via " + (executable instanceof Constructor ? "constructor" : "factory method") + " to bean named '" + autowiredBeanName + "'");
}
}
return args;
}
use of org.springframework.core.MethodParameter in project spring-framework by spring-projects.
the class ConstructorResolver method resolvePreparedArguments.
/**
* Resolve the prepared arguments stored in the given bean definition.
*/
private Object[] resolvePreparedArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, Executable executable, Object[] argsToResolve) {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
Class<?>[] paramTypes = executable.getParameterTypes();
Object[] resolvedArgs = new Object[argsToResolve.length];
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
Object argValue = argsToResolve[argIndex];
MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
GenericTypeResolver.resolveParameterType(methodParam, executable.getDeclaringClass());
if (argValue instanceof AutowiredArgumentMarker) {
argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
} else if (argValue instanceof BeanMetadataElement) {
argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
} else if (argValue instanceof String) {
argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
}
Class<?> paramType = paramTypes[argIndex];
try {
resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam);
} catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(argValue) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
}
return resolvedArgs;
}
use of org.springframework.core.MethodParameter in project spring-framework by spring-projects.
the class QualifierAnnotationAutowireBeanFactoryTests method testAutowireCandidateWithMultipleCandidatesDescriptor.
@Test
public void testAutowireCandidateWithMultipleCandidatesDescriptor() throws Exception {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
ConstructorArgumentValues cavs1 = new ConstructorArgumentValues();
cavs1.addGenericArgumentValue(JUERGEN);
RootBeanDefinition person1 = new RootBeanDefinition(Person.class, cavs1, null);
person1.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
lbf.registerBeanDefinition(JUERGEN, person1);
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
cavs2.addGenericArgumentValue(MARK);
RootBeanDefinition person2 = new RootBeanDefinition(Person.class, cavs2, null);
person2.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
lbf.registerBeanDefinition(MARK, person2);
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(new MethodParameter(QualifiedTestBean.class.getDeclaredConstructor(Person.class), 0), false);
assertTrue(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor));
assertTrue(lbf.isAutowireCandidate(MARK, qualifiedDescriptor));
}
use of org.springframework.core.MethodParameter in project spring-framework by spring-projects.
the class TypeDescriptorTests method nestedMethodParameterTypeMap.
@Test
public void nestedMethodParameterTypeMap() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test3", Map.class), 0), 1);
assertEquals(String.class, t1.getType());
}
use of org.springframework.core.MethodParameter in project spring-framework by spring-projects.
the class TypeDescriptorTests method nestedMethodParameterType2Levels.
@Test
public void nestedMethodParameterType2Levels() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test2", List.class), 0), 2);
assertEquals(String.class, t1.getType());
}
Aggregations