diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 9c34512c01..4e7c65c36e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -667,33 +667,40 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac factoryMethod.getParameterTypes().length >= minNrOfArgs) { // No declared type variables to inspect, so just process the standard return type. if (factoryMethod.getTypeParameters().length > 0) { - // Fully resolve parameter names and argument values. - Class[] paramTypes = factoryMethod.getParameterTypes(); - String[] paramNames = null; - ParameterNameDiscoverer pnd = getParameterNameDiscoverer(); - if (pnd != null) { - paramNames = pnd.getParameterNames(factoryMethod); - } - ConstructorArgumentValues cav = mbd.getConstructorArgumentValues(); - Set usedValueHolders = - new HashSet(paramTypes.length); - Object[] args = new Object[paramTypes.length]; - for (int i = 0; i < args.length; i++) { - ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue( - i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders); - if (valueHolder == null) { - valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders); + try { + // Fully resolve parameter names and argument values. + Class[] paramTypes = factoryMethod.getParameterTypes(); + String[] paramNames = null; + ParameterNameDiscoverer pnd = getParameterNameDiscoverer(); + if (pnd != null) { + paramNames = pnd.getParameterNames(factoryMethod); + } + ConstructorArgumentValues cav = mbd.getConstructorArgumentValues(); + Set usedValueHolders = + new HashSet(paramTypes.length); + Object[] args = new Object[paramTypes.length]; + for (int i = 0; i < args.length; i++) { + ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue( + i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders); + if (valueHolder == null) { + valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders); + } + if (valueHolder != null) { + args[i] = valueHolder.getValue(); + usedValueHolders.add(valueHolder); + } } - if (valueHolder != null) { - args[i] = valueHolder.getValue(); - usedValueHolders.add(valueHolder); + Class returnType = AutowireUtils.resolveReturnTypeForFactoryMethod( + factoryMethod, args, getBeanClassLoader()); + if (returnType != null) { + cache = true; + returnTypes.add(returnType); } } - Class returnType = AutowireUtils.resolveReturnTypeForFactoryMethod( - factoryMethod, args, getBeanClassLoader()); - if (returnType != null) { - cache = true; - returnTypes.add(returnType); + catch (Throwable ex) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to resolve generic return type for factory method: " + ex); + } } } else { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java index 2e25d1904a..a9e574629f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java @@ -223,7 +223,8 @@ abstract class AutowireUtils { return typedValue.resolveTargetType(classLoader); } catch (ClassNotFoundException ex) { - throw new IllegalStateException("Failed to resolve typed value", ex); + throw new IllegalStateException("Failed to resolve value type [" + + typedValue.getTargetTypeName() + "] for factory method argument", ex); } } // Only consider argument type if it is a simple value... @@ -254,11 +255,11 @@ abstract class AutowireUtils { } if (className != null) { try { - return classLoader.loadClass(className); + return ClassUtils.forName(className, classLoader); } catch (ClassNotFoundException ex) { - throw new IllegalStateException( - "Could not resolve specified class name argument [" + arg + "]", ex); + throw new IllegalStateException("Could not resolve class name [" + arg + + "] for factory method argument", ex); } } // Consider adding logic to determine the class of the typeArg, if possible. diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java index f35b2a5193..f2b33f22dc 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanFactoryGenericsTests.java @@ -735,6 +735,23 @@ public class BeanFactoryGenericsTests { assertEquals(1, beans.size()); } + @Test + public void parameterizedInstanceFactoryMethodWithInvalidClassName() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + + RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class); + bf.registerBeanDefinition("mocksControl", rbd); + + rbd = new RootBeanDefinition(); + rbd.setFactoryBeanName("mocksControl"); + rbd.setFactoryMethodName("createMock"); + rbd.getConstructorArgumentValues().addGenericArgumentValue("x"); + bf.registerBeanDefinition("mock", rbd); + + Map beans = bf.getBeansOfType(Runnable.class); + assertEquals(0, beans.size()); + } + @Test public void parameterizedInstanceFactoryMethodWithIndexedArgument() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory();