Consistent throwing of last UnsatisfiedDependencyException if available and no constructor resolved

Issue: SPR-12543
master
Juergen Hoeller 10 years ago
parent cae217de94
commit d55af2b445
  1. 29
      spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
  2. 38
      spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

@ -157,7 +157,7 @@ class ConstructorResolver {
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
List<Exception> causes = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (int i = 0; i < candidates.length; i++) {
Constructor<?> candidate = candidates[i];
@ -190,22 +190,12 @@ class ConstructorResolver {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
if (i == candidates.length - 1 && constructorToUse == null) {
if (causes != null) {
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
}
throw ex;
}
else {
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<Exception>();
}
causes.add(ex);
continue;
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<UnsatisfiedDependencyException>();
}
causes.add(ex);
continue;
}
}
else {
@ -236,6 +226,13 @@ class ConstructorResolver {
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");

@ -2023,6 +2023,30 @@ public class DefaultListableBeanFactoryTests {
lbf.preInstantiateSingletons();
}
@Test
public void testConstructorDependencyWithClassResolution() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.String");
lbf.registerBeanDefinition("test", bd);
lbf.preInstantiateSingletons();
}
@Test
public void testConstructorDependencyWithUnresolvableClass() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(ConstructorDependencyWithClassResolution.class);
bd.getConstructorArgumentValues().addGenericArgumentValue("java.lang.Strin");
lbf.registerBeanDefinition("test", bd);
try {
lbf.preInstantiateSingletons();
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (UnsatisfiedDependencyException expected) {
assertTrue(expected.toString().contains("java.lang.Strin"));
}
}
@Test
public void testBeanDefinitionWithInterface() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
@ -2033,7 +2057,7 @@ public class DefaultListableBeanFactoryTests {
}
catch (BeanCreationException ex) {
assertEquals("test", ex.getBeanName());
assertTrue(ex.getMessage().toLowerCase().indexOf("interface") != -1);
assertTrue(ex.getMessage().toLowerCase().contains("interface"));
}
}
@ -2047,7 +2071,7 @@ public class DefaultListableBeanFactoryTests {
}
catch (BeanCreationException ex) {
assertEquals("test", ex.getBeanName());
assertTrue(ex.getMessage().toLowerCase().indexOf("abstract") != -1);
assertTrue(ex.getMessage().toLowerCase().contains("abstract"));
}
}
@ -2739,6 +2763,16 @@ public class DefaultListableBeanFactoryTests {
}
public static class ConstructorDependencyWithClassResolution {
public ConstructorDependencyWithClassResolution(Class<?> clazz) {
}
public ConstructorDependencyWithClassResolution() {
}
}
public static class BeanWithDisposableBean implements DisposableBean {
private static boolean closed;

Loading…
Cancel
Save