Consistent UnsatisfiedDependencyException exposure with injection point metadata

Issue: SPR-13968
This commit is contained in:
Juergen Hoeller
2016-02-25 21:36:49 +01:00
parent 4c964473b1
commit b6dd8a9233
10 changed files with 428 additions and 188 deletions

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2016 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;
import org.junit.Test;
@@ -49,8 +65,7 @@ public class Spr5475Tests {
cav.addIndexedArgumentValue(1, "bogusArg2".getBytes());
def.setConstructorArgumentValues(cav);
assertExceptionMessageForMisconfiguredFactoryMethod(
def,
assertExceptionMessageForMisconfiguredFactoryMethod(def,
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -62,7 +77,8 @@ public class Spr5475Tests {
try {
factory.preInstantiateSingletons();
fail("should have failed with BeanCreationException due to incorrectly invoked factory method");
} catch (BeanCreationException ex) {
}
catch (BeanCreationException ex) {
assertThat(ex.getMessage(), equalTo(expectedMessage));
}
}
@@ -72,15 +88,17 @@ public class Spr5475Tests {
// calling a factory method that accepts arguments without any arguments emits an exception unlike cases
// where a no-arg factory method is called with arguments. Adding this test just to document the difference
assertExceptionMessageForMisconfiguredFactoryMethod(
rootBeanDefinition(Foo.class)
.setFactoryMethod("singleArgFactory").getBeanDefinition(),
rootBeanDefinition(Foo.class).
setFactoryMethod("singleArgFactory").getBeanDefinition(),
"Error creating bean with name 'foo': " +
"Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: " +
"Ambiguous factory method argument types - did you specify the correct bean references as factory method arguments?");
"Unsatisfied dependency expressed through method 'singleArgFactory' parameter 0: " +
"Ambiguous argument values for parameter of type [java.lang.String] - " +
"did you specify the correct bean references as arguments?");
}
static class Foo {
static Foo noArgFactory() {
return new Foo();
}

View File

@@ -83,6 +83,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.registerBeanDefinition("testBean", new GenericBeanDefinition());
try {
bf.getBean("testBean");
fail("Should have thrown BeanCreationException");
}
catch (BeanCreationException ex) {
assertTrue(ex.getRootCause() instanceof IllegalStateException);
@@ -635,6 +636,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
}
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(ConstructorWithoutFallbackBean.class, ex.getInjectionPoint().getMethodParameter().getDeclaringClass());
}
}
@@ -838,8 +840,9 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.getBean("annotatedBean");
fail("should have failed, more than one bean of type");
}
catch (BeanCreationException ex) {
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(MapMethodInjectionBean.class, ex.getInjectionPoint().getMethodParameter().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -1164,7 +1167,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
CustomAnnotationRequiredFieldResourceInjectionBean bean = (CustomAnnotationRequiredFieldResourceInjectionBean) bf.getBean("customBean");
CustomAnnotationRequiredFieldResourceInjectionBean bean =
(CustomAnnotationRequiredFieldResourceInjectionBean) bf.getBean("customBean");
assertSame(tb, bean.getTestBean());
bf.destroySingletons();
}
@@ -1183,10 +1187,12 @@ public class AutowiredAnnotationBeanPostProcessorTests {
try {
bf.getBean("customBean");
fail("expected BeanCreationException; no dependency available for required field");
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (BeanCreationException ex) {
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(CustomAnnotationRequiredFieldResourceInjectionBean.class,
ex.getInjectionPoint().getField().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -1209,10 +1215,13 @@ public class AutowiredAnnotationBeanPostProcessorTests {
try {
bf.getBean("customBean");
fail("expected BeanCreationException; multiple beans of dependency type available");
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (BeanCreationException ex) {
catch (UnsatisfiedDependencyException ex) {
// expected
ex.printStackTrace();
assertSame(CustomAnnotationRequiredFieldResourceInjectionBean.class,
ex.getInjectionPoint().getField().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -1231,7 +1240,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
CustomAnnotationRequiredMethodResourceInjectionBean bean = (CustomAnnotationRequiredMethodResourceInjectionBean) bf.getBean("customBean");
CustomAnnotationRequiredMethodResourceInjectionBean bean =
(CustomAnnotationRequiredMethodResourceInjectionBean) bf.getBean("customBean");
assertSame(tb, bean.getTestBean());
bf.destroySingletons();
}
@@ -1250,10 +1260,12 @@ public class AutowiredAnnotationBeanPostProcessorTests {
try {
bf.getBean("customBean");
fail("expected BeanCreationException; no dependency available for required method");
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (BeanCreationException e) {
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(CustomAnnotationRequiredMethodResourceInjectionBean.class,
ex.getInjectionPoint().getMethodParameter().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -1276,10 +1288,12 @@ public class AutowiredAnnotationBeanPostProcessorTests {
try {
bf.getBean("customBean");
fail("expected BeanCreationException; multiple beans of dependency type available");
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (BeanCreationException ex) {
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(CustomAnnotationRequiredMethodResourceInjectionBean.class,
ex.getInjectionPoint().getMethodParameter().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -1298,7 +1312,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
CustomAnnotationOptionalFieldResourceInjectionBean bean = (CustomAnnotationOptionalFieldResourceInjectionBean) bf.getBean("customBean");
CustomAnnotationOptionalFieldResourceInjectionBean bean =
(CustomAnnotationOptionalFieldResourceInjectionBean) bf.getBean("customBean");
assertSame(tb, bean.getTestBean3());
assertNull(bean.getTestBean());
assertNull(bean.getTestBean2());
@@ -1317,7 +1332,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.registerBeanDefinition("customBean", new RootBeanDefinition(
CustomAnnotationOptionalFieldResourceInjectionBean.class));
CustomAnnotationOptionalFieldResourceInjectionBean bean = (CustomAnnotationOptionalFieldResourceInjectionBean) bf.getBean("customBean");
CustomAnnotationOptionalFieldResourceInjectionBean bean =
(CustomAnnotationOptionalFieldResourceInjectionBean) bf.getBean("customBean");
assertNull(bean.getTestBean3());
assertNull(bean.getTestBean());
assertNull(bean.getTestBean2());
@@ -1342,10 +1358,12 @@ public class AutowiredAnnotationBeanPostProcessorTests {
try {
bf.getBean("customBean");
fail("expected BeanCreationException; multiple beans of dependency type available");
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (BeanCreationException ex) {
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(CustomAnnotationOptionalFieldResourceInjectionBean.class,
ex.getInjectionPoint().getField().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -1364,7 +1382,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
CustomAnnotationOptionalMethodResourceInjectionBean bean = (CustomAnnotationOptionalMethodResourceInjectionBean) bf.getBean("customBean");
CustomAnnotationOptionalMethodResourceInjectionBean bean =
(CustomAnnotationOptionalMethodResourceInjectionBean) bf.getBean("customBean");
assertSame(tb, bean.getTestBean3());
assertNull(bean.getTestBean());
assertNull(bean.getTestBean2());
@@ -1383,7 +1402,8 @@ public class AutowiredAnnotationBeanPostProcessorTests {
bf.registerBeanDefinition("customBean", new RootBeanDefinition(
CustomAnnotationOptionalMethodResourceInjectionBean.class));
CustomAnnotationOptionalMethodResourceInjectionBean bean = (CustomAnnotationOptionalMethodResourceInjectionBean) bf.getBean("customBean");
CustomAnnotationOptionalMethodResourceInjectionBean bean =
(CustomAnnotationOptionalMethodResourceInjectionBean) bf.getBean("customBean");
assertNull(bean.getTestBean3());
assertNull(bean.getTestBean());
assertNull(bean.getTestBean2());
@@ -1408,10 +1428,12 @@ public class AutowiredAnnotationBeanPostProcessorTests {
try {
bf.getBean("customBean");
fail("expected BeanCreationException; multiple beans of dependency type available");
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (BeanCreationException ex) {
catch (UnsatisfiedDependencyException ex) {
// expected
assertSame(CustomAnnotationOptionalMethodResourceInjectionBean.class,
ex.getInjectionPoint().getMethodParameter().getDeclaringClass());
}
bf.destroySingletons();
}
@@ -2644,7 +2666,7 @@ public class AutowiredAnnotationBeanPostProcessorTests {
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public static @interface MyAutowired {
public @interface MyAutowired {
boolean optional() default false;
}