Defensive handling of exceptions during factory method type checking
Also using ClassUtils.forName in AutowireUtils now in order to accept all common class name formats. Issue: SPR-11034
This commit is contained in:
@@ -667,6 +667,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||||||
factoryMethod.getParameterTypes().length >= minNrOfArgs) {
|
factoryMethod.getParameterTypes().length >= minNrOfArgs) {
|
||||||
// No declared type variables to inspect, so just process the standard return type.
|
// No declared type variables to inspect, so just process the standard return type.
|
||||||
if (factoryMethod.getTypeParameters().length > 0) {
|
if (factoryMethod.getTypeParameters().length > 0) {
|
||||||
|
try {
|
||||||
// Fully resolve parameter names and argument values.
|
// Fully resolve parameter names and argument values.
|
||||||
Class<?>[] paramTypes = factoryMethod.getParameterTypes();
|
Class<?>[] paramTypes = factoryMethod.getParameterTypes();
|
||||||
String[] paramNames = null;
|
String[] paramNames = null;
|
||||||
@@ -696,6 +697,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||||||
returnTypes.add(returnType);
|
returnTypes.add(returnType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Failed to resolve generic return type for factory method: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
returnTypes.add(factoryMethod.getReturnType());
|
returnTypes.add(factoryMethod.getReturnType());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,8 @@ abstract class AutowireUtils {
|
|||||||
return typedValue.resolveTargetType(classLoader);
|
return typedValue.resolveTargetType(classLoader);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException ex) {
|
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...
|
// Only consider argument type if it is a simple value...
|
||||||
@@ -254,11 +255,11 @@ abstract class AutowireUtils {
|
|||||||
}
|
}
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
try {
|
try {
|
||||||
return classLoader.loadClass(className);
|
return ClassUtils.forName(className, classLoader);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException ex) {
|
catch (ClassNotFoundException ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("Could not resolve class name [" + arg +
|
||||||
"Could not resolve specified class name argument [" + arg + "]", ex);
|
"] for factory method argument", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Consider adding logic to determine the class of the typeArg, if possible.
|
// Consider adding logic to determine the class of the typeArg, if possible.
|
||||||
|
|||||||
@@ -735,6 +735,23 @@ public class BeanFactoryGenericsTests {
|
|||||||
assertEquals(1, beans.size());
|
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<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
|
||||||
|
assertEquals(0, beans.size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parameterizedInstanceFactoryMethodWithIndexedArgument() {
|
public void parameterizedInstanceFactoryMethodWithIndexedArgument() {
|
||||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||||
|
|||||||
Reference in New Issue
Block a user