alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (ConstructorResolver.java)

This example Spring Framework source code file (ConstructorResolver.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

argumentsholder, argumentsholder, beanwrapperimpl, class, constructor, constructorargumentvalues, constructorargumentvalues, methodparameter, object, object, reflection, string, string, typeconverter, unsatisfieddependencyexception, util

The Spring Framework ConstructorResolver.java source code

/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.support;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.JdkVersion;
import org.springframework.core.MethodParameter;
import org.springframework.util.MethodInvoker;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

/**
 * Helper class for resolving constructors and factory methods.
 * Performs constructor resolution through argument matching.
 *
 * <p>Operates on an {@link AbstractBeanFactory} and an {@link InstantiationStrategy}.
 * Used by {@link AbstractAutowireCapableBeanFactory}.
 *
 * @author Juergen Hoeller
 * @author Rob Harrop
 * @author Mark Fisher
 * @since 2.0
 * @see #autowireConstructor
 * @see #instantiateUsingFactoryMethod
 * @see AbstractAutowireCapableBeanFactory
 */
class ConstructorResolver {

	private final AbstractBeanFactory beanFactory;

	private final AutowireCapableBeanFactory autowireFactory;

	private final InstantiationStrategy instantiationStrategy;

	private final TypeConverter typeConverter;


	/**
	 * Create a new ConstructorResolver for the given factory and instantiation strategy.
	 * @param beanFactory the BeanFactory to work with
	 * @param autowireFactory the BeanFactory as AutowireCapableBeanFactory
	 * @param instantiationStrategy the instantiate strategy for creating bean instances
	 * @param typeConverter the TypeConverter to use (or <code>null for using the default)
	 */
	public ConstructorResolver(AbstractBeanFactory beanFactory, AutowireCapableBeanFactory autowireFactory,
			InstantiationStrategy instantiationStrategy, TypeConverter typeConverter) {

		this.beanFactory = beanFactory;
		this.autowireFactory = autowireFactory;
		this.instantiationStrategy = instantiationStrategy;
		this.typeConverter = typeConverter;
	}


	/**
	 * "autowire constructor" (with constructor arguments by type) behavior.
	 * Also applied if explicit constructor argument values are specified,
	 * matching all remaining arguments with beans from the bean factory.
	 * <p>This corresponds to constructor injection: In this mode, a Spring
	 * bean factory is able to host components that expect constructor-based
	 * dependency resolution.
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition for the bean
	 * @param chosenCtors chosen candidate constructors (or <code>null if none)
	 * @param explicitArgs argument values passed in programmatically via the getBean method,
	 * or <code>null if none (-> use constructor argument values from bean definition)
	 * @return a BeanWrapper for the new instance
	 */
	protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, Constructor[] chosenCtors, Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Constructor constructorToUse = null;
		Object[] argsToUse = null;

		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod;
			if (constructorToUse != null) {
				// Found a cached constructor...
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					Class[] paramTypes = constructorToUse.getParameterTypes();
					Object[] argsToResolve = mbd.preparedConstructorArguments;
					TypeConverter converter = (this.typeConverter != null ? this.typeConverter : bw);
					BeanDefinitionValueResolver valueResolver =
							new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
					argsToUse = new Object[argsToResolve.length];
					for (int i = 0; i < argsToResolve.length; i++) {
						Object argValue = argsToResolve[i];
						MethodParameter methodParam = new MethodParameter(constructorToUse, i);
						if (JdkVersion.isAtLeastJava15()) {
							GenericTypeResolver.resolveParameterType(methodParam, constructorToUse.getDeclaringClass());
						}
						if (argValue instanceof AutowiredArgumentMarker) {
							argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
						}
						else if (argValue instanceof BeanMetadataElement) {
							argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
						}
						argsToUse[i] = converter.convertIfNecessary(argValue, paramTypes[i], methodParam);
					}
				}
			}
		}

		if (constructorToUse == null) {
			// Need to resolve the constructor.
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs = 0;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				resolvedValues = new ConstructorArgumentValues();
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			// Take specified constructors, if any.
			Constructor[] candidates =
					(chosenCtors != null ? chosenCtors : mbd.getBeanClass().getDeclaredConstructors());
			AutowireUtils.sortConstructors(candidates);
			int minTypeDiffWeight = Integer.MAX_VALUE;

			for (int i = 0; i < candidates.length; i++) {
				Constructor candidate = candidates[i];
				Class[] paramTypes = candidate.getParameterTypes();

				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					// Already found greedy constructor that can be satisfied ->
					// do not look any further, there are only less greedy constructors left.
					break;
				}
				if (paramTypes.length < minNrOfArgs) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							minNrOfArgs + " constructor arguments specified but no matching constructor found in bean '" +
							beanName + "' " +
							"(hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)");
				}

				ArgumentsHolder args = null;

				if (resolvedValues != null) {
					// Try to resolve arguments for current constructor.
					try {
						args = createArgumentArray(
								beanName, mbd, resolvedValues, bw, paramTypes, candidate, autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (this.beanFactory.logger.isTraceEnabled()) {
							this.beanFactory.logger.trace(
									"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						if (i == candidates.length - 1 && constructorToUse == null) {
							throw ex;
						}
						else {
							// Swallow and try next constructor.
							this.beanFactory.onSuppressedException(ex);
							continue;
						}
					}
				}

				else {
					// Explicit arguments given -> arguments length must match exactly.
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					args = new ArgumentsHolder(explicitArgs);
				}

				int typeDiffWeight = args.getTypeDifferenceWeight(paramTypes);
				// Choose this constructor if it represents the closest match.
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsToUse = args.arguments;
					minTypeDiffWeight = typeDiffWeight;
				}
			}

			if (constructorToUse == null) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Could not resolve matching constructor");
			}

			if (explicitArgs == null) {
				mbd.resolvedConstructorOrFactoryMethod = constructorToUse;
			}
		}

		try {
			Object beanInstance = this.instantiationStrategy.instantiate(
					mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			bw.setWrappedInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

	/**
	 * Instantiate the bean using a named factory method. The method may be static, if the
	 * bean definition parameter specifies a class, rather than a "factory-bean", or
	 * an instance variable on a factory object itself configured using Dependency Injection.
	 * <p>Implementation requires iterating over the static or instance methods with the
	 * name specified in the RootBeanDefinition (the method may be overloaded) and trying
	 * to match with the parameters. We don't have the types attached to constructor args,
	 * so trial and error is the only way to go here. The explicitArgs array may contain
	 * argument values passed in programmatically via the corresponding getBean method.
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition for the bean
	 * @param explicitArgs argument values passed in programmatically via the getBean
	 * method, or <code>null if none (-> use constructor argument values from bean definition)
	 * @return a BeanWrapper for the new instance
	 */
	public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Class factoryClass = null;
		Object factoryBean = null;
		boolean isStatic = true;

		String factoryBeanName = mbd.getFactoryBeanName();
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			if (factoryBean == null) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"factory-bean '" + factoryBeanName + "' returned null");
			}
			factoryClass = factoryBean.getClass();
			isStatic = false;
		}
		else {
			// It's a static factory method on the bean class.
			factoryClass = mbd.getBeanClass();
		}

		Method factoryMethodToUse = null;
		Object[] argsToUse = null;

		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
			if (factoryMethodToUse != null) {
				// Found a cached factory method...
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					Class[] paramTypes = factoryMethodToUse.getParameterTypes();
					Object[] argsToResolve = mbd.preparedConstructorArguments;
					TypeConverter converter = (this.typeConverter != null ? this.typeConverter : bw);
					BeanDefinitionValueResolver valueResolver =
							new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
					argsToUse = new Object[argsToResolve.length];
					for (int i = 0; i < argsToResolve.length; i++) {
						Object argValue = argsToResolve[i];
						MethodParameter methodParam = new MethodParameter(factoryMethodToUse, i);
						if (JdkVersion.isAtLeastJava15()) {
							GenericTypeResolver.resolveParameterType(methodParam, factoryClass);
						}
						if (argValue instanceof AutowiredArgumentMarker) {
							argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
						}
						else if (argValue instanceof BeanMetadataElement) {
							argValue = valueResolver.resolveValueIfNecessary("factory method argument", argValue);
						}
						argsToUse[i] = converter.convertIfNecessary(argValue, paramTypes[i], methodParam);
					}
				}
			}
		}

		if (factoryMethodToUse == null) {
			// Need to determine the factory method...
			// Try all methods with this name to see if they match the given arguments.
			Method[] candidates = ReflectionUtils.getAllDeclaredMethods(factoryClass);
			boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs = 0;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				// We don't have arguments passed in programmatically, so we need to resolve the
				// arguments specified in the constructor arguments held in the bean definition.
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				resolvedValues = new ConstructorArgumentValues();
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			for (int i = 0; i < candidates.length; i++) {
				Method candidate = candidates[i];
				Class[] paramTypes = candidate.getParameterTypes();

				if (Modifier.isStatic(candidate.getModifiers()) == isStatic &&
						candidate.getName().equals(mbd.getFactoryMethodName()) &&
						paramTypes.length >= minNrOfArgs) {

					ArgumentsHolder args = null;

					if (resolvedValues != null) {
						// Resolved contructor arguments: type conversion and/or autowiring necessary.
						try {
							args = createArgumentArray(
									beanName, mbd, resolvedValues, bw, paramTypes, candidate, autowiring);
						}
						catch (UnsatisfiedDependencyException ex) {
							if (this.beanFactory.logger.isTraceEnabled()) {
								this.beanFactory.logger.trace("Ignoring factory method [" + candidate +
										"] of bean '" + beanName + "': " + ex);
							}
							if (i == candidates.length - 1 && factoryMethodToUse == null) {
								throw ex;
							}
							else {
								// Swallow and try next overloaded factory method.
								this.beanFactory.onSuppressedException(ex);
								continue;
							}
						}
					}

					else {
						// Explicit arguments given -> arguments length must match exactly.
						if (paramTypes.length != explicitArgs.length) {
							continue;
						}
						args = new ArgumentsHolder(explicitArgs);
					}

					int typeDiffWeight = args.getTypeDifferenceWeight(paramTypes);
					// Choose this constructor if it represents the closest match.
					if (typeDiffWeight < minTypeDiffWeight) {
						factoryMethodToUse = candidate;
						argsToUse = args.arguments;
						minTypeDiffWeight = typeDiffWeight;
					}
				}
			}

			if (factoryMethodToUse == null) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"No matching factory method found: " +
						(mbd.getFactoryBeanName() != null ?
						 "factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
						"factory method '" + mbd.getFactoryMethodName() + "'");
			}
			if (void.class.equals(factoryMethodToUse.getReturnType())) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid factory method '" + mbd.getFactoryMethodName() +
						"': needs to have a non-void return type!");
			}

			if (explicitArgs == null) {
				mbd.resolvedConstructorOrFactoryMethod = factoryMethodToUse;
			}
		}

		try {
			Object beanInstance = this.instantiationStrategy.instantiate(
					mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
			if (beanInstance == null) {
				return null;
			}
			bw.setWrappedInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

	/**
	 * Resolve the constructor arguments for this bean into the resolvedValues object.
	 * This may involve looking up other beans.
	 * This method is also used for handling invocations of static factory methods.
	 */
	private int resolveConstructorArguments(
			String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

		TypeConverter converterToUse = (this.typeConverter != null ? this.typeConverter : bw);
		BeanDefinitionValueResolver valueResolver =
				new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converterToUse);

		int minNrOfArgs = cargs.getArgumentCount();

		for (Iterator it = cargs.getIndexedArgumentValues().entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			int index = ((Integer) entry.getKey()).intValue();
			if (index < 0) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid constructor argument index: " + index);
			}
			if (index > minNrOfArgs) {
				minNrOfArgs = index + 1;
			}
			ConstructorArgumentValues.ValueHolder valueHolder =
					(ConstructorArgumentValues.ValueHolder) entry.getValue();
			if (valueHolder.isConverted()) {
				resolvedValues.addIndexedArgumentValue(index, valueHolder);
			}
			else {
				Object resolvedValue =
						valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				ConstructorArgumentValues.ValueHolder resolvedValueHolder =
						new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
			}
		}

		for (Iterator it = cargs.getGenericArgumentValues().iterator(); it.hasNext();) {
			ConstructorArgumentValues.ValueHolder valueHolder =
					(ConstructorArgumentValues.ValueHolder) it.next();
			if (valueHolder.isConverted()) {
				resolvedValues.addGenericArgumentValue(valueHolder);
			}
			else {
				Object resolvedValue =
						valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				ConstructorArgumentValues.ValueHolder resolvedValueHolder =
						new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addGenericArgumentValue(resolvedValueHolder);
			}
		}

		return minNrOfArgs;
	}

	/**
	 * 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, Object methodOrCtor, boolean autowiring)
			throws UnsatisfiedDependencyException {

		String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
		TypeConverter converter = (this.typeConverter != null ? this.typeConverter : bw);

		ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
		Set usedValueHolders = new HashSet(paramTypes.length);
		Set autowiredBeanNames = new LinkedHashSet(4);
		boolean resolveNecessary = false;

		for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
			Class paramType = paramTypes[paramIndex];
			// Try to find matching constructor argument value, either indexed or generic.
			ConstructorArgumentValues.ValueHolder valueHolder =
					resolvedValues.getArgumentValue(paramIndex, paramType, usedValueHolders);
			// If we couldn't find a direct match and are not supposed to autowire,
			// let's try the next generic, untyped argument value as fallback:
			// it could match after type conversion (for example, String -> int).
			if (valueHolder == null && !autowiring) {
				valueHolder = resolvedValues.getGenericArgumentValue(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);
				args.rawArguments[paramIndex] = valueHolder.getValue();
				if (valueHolder.isConverted()) {
					Object convertedValue = valueHolder.getConvertedValue();
					args.arguments[paramIndex] = convertedValue;
					args.preparedArguments[paramIndex] = convertedValue;
				}
				else {
					try {
						Object originalValue = valueHolder.getValue();
						Object convertedValue = converter.convertIfNecessary(originalValue, paramType,
								MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex));
						args.arguments[paramIndex] = convertedValue;
						ConstructorArgumentValues.ValueHolder sourceHolder =
								(ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
						Object sourceValue = sourceHolder.getValue();
						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 {
							resolveNecessary = true;
							args.preparedArguments[paramIndex] = sourceValue;
						}
					}
					catch (TypeMismatchException ex) {
						throw new UnsatisfiedDependencyException(
								mbd.getResourceDescription(), beanName, paramIndex, paramType,
								"Could not convert " + methodType + " argument value of type [" +
								ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
								"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
					}
				}
			}
			else {
				// No explicit match found: we're either supposed to autowire or
				// have to fail creating an argument array for the given constructor.
				if (!autowiring) {
					throw new UnsatisfiedDependencyException(
							mbd.getResourceDescription(), beanName, paramIndex, paramType,
							"Ambiguous " + methodType + " argument types - " +
							"did you specify the correct bean references as " + methodType + " arguments?");
				}
				try {
					MethodParameter param = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
					Object autowiredArgument = resolveAutowiredArgument(param, beanName, autowiredBeanNames, converter);
					args.rawArguments[paramIndex] = autowiredArgument;
					args.arguments[paramIndex] = autowiredArgument;
					args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
					resolveNecessary = true;
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(
							mbd.getResourceDescription(), beanName, paramIndex, paramType, ex.getMessage());
				}
			}
		}

		for (Iterator it = autowiredBeanNames.iterator(); it.hasNext();) {
			String autowiredBeanName = (String) it.next();
			this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
			if (this.beanFactory.logger.isDebugEnabled()) {
				this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName +
						"' via " + methodType + " to bean named '" + autowiredBeanName + "'");
			}
		}

		if (resolveNecessary) {
			mbd.preparedConstructorArguments = args.preparedArguments;
		}
		else {
			mbd.resolvedConstructorArguments = args.arguments;
		}
		mbd.constructorArgumentsResolved = true;
		return args;
	}

	/**
	 * Template method for resolving the specified argument which is supposed to be autowired.
	 */
	protected Object resolveAutowiredArgument(
			MethodParameter param, String beanName, Set autowiredBeanNames, TypeConverter typeConverter) {

		return this.autowireFactory.resolveDependency(
				new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
	}


	/**
	 * Private inner class for holding argument combinations.
	 */
	private static class ArgumentsHolder {

		public Object rawArguments[];

		public Object arguments[];

		public Object preparedArguments[];

		public ArgumentsHolder(int size) {
			this.rawArguments = new Object[size];
			this.arguments = new Object[size];
			this.preparedArguments = new Object[size];
		}

		public ArgumentsHolder(Object[] args) {
			this.rawArguments = args;
			this.arguments = args;
			this.preparedArguments = args;
		}

		public int getTypeDifferenceWeight(Class[] paramTypes) {
			// If valid arguments found, determine type difference weight.
			// Try type difference weight on both the converted arguments and
			// the raw arguments. If the raw weight is better, use it.
			// Decrease raw weight by 1024 to prefer it over equal converted weight.
			int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
			int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
			return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight);
		}
	}


	/**
	 * Marker for autowired arguments in a cached argument array.
 	 */
	private static class AutowiredArgumentMarker {
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework ConstructorResolver.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.