Supplier registration support for annotated bean classes

Issue: SPR-14832
This commit is contained in:
Juergen Hoeller
2016-12-20 19:57:44 +01:00
parent 3b987c263c
commit 9005481a49
3 changed files with 294 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* 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.
@@ -86,7 +86,7 @@ public class AnnotationConfigApplicationContextTests {
public void getBeanByType() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
TestBean testBean = context.getBean(TestBean.class);
assertNotNull("getBean() should not return null", testBean);
assertNotNull(testBean);
assertThat(testBean.name, equalTo("foo"));
}
@@ -116,6 +116,102 @@ public class AnnotationConfigApplicationContextTests {
assertNotNull(configObject);
}
@Test
public void individualBeans() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(BeanA.class, BeanB.class, BeanC.class);
context.refresh();
assertSame(context.getBean(BeanB.class), context.getBean(BeanA.class).b);
assertSame(context.getBean(BeanC.class), context.getBean(BeanA.class).c);
assertSame(context, context.getBean(BeanB.class).applicationContext);
}
@Test
public void individualNamedBeans() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean("a", BeanA.class);
context.registerBean("b", BeanB.class);
context.registerBean("c", BeanC.class);
context.refresh();
assertSame(context.getBean("b"), context.getBean("a", BeanA.class).b);
assertSame(context.getBean("c"), context.getBean("a", BeanA.class).c);
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
}
@Test
public void individualBeanWithSupplier() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean(BeanA.class,
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)));
context.registerBean(BeanB.class, BeanB::new);
context.registerBean(BeanC.class, BeanC::new);
context.refresh();
assertSame(context.getBean(BeanB.class), context.getBean(BeanA.class).b);
assertSame(context.getBean(BeanC.class), context.getBean(BeanA.class).c);
assertSame(context, context.getBean(BeanB.class).applicationContext);
}
@Test
public void individualNamedBeanWithSupplier() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBean("a", BeanA.class,
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)));
context.registerBean("b", BeanB.class, BeanB::new);
context.registerBean("c", BeanC.class, BeanC::new);
context.refresh();
assertSame(context.getBean("b", BeanB.class), context.getBean(BeanA.class).b);
assertSame(context.getBean("c"), context.getBean("a", BeanA.class).c);
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
}
@Test
public void individualBeanWithSpecifiedConstructorArguments() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
BeanB b = new BeanB();
BeanC c = new BeanC();
context.registerBean(BeanA.class, b, c);
context.refresh();
assertSame(b, context.getBean(BeanA.class).b);
assertSame(c, context.getBean(BeanA.class).c);
assertNull(b.applicationContext);
}
@Test
public void individualNamedBeanWithSpecifiedConstructorArguments() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
BeanB b = new BeanB();
BeanC c = new BeanC();
context.registerBean("a", BeanA.class, b, c);
context.refresh();
assertSame(b, context.getBean("a", BeanA.class).b);
assertSame(c, context.getBean("a", BeanA.class).c);
assertNull(b.applicationContext);
}
@Test
public void individualBeanWithMixedConstructorArguments() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
BeanC c = new BeanC();
context.registerBean(BeanA.class, c);
context.registerBean(BeanB.class);
context.refresh();
assertSame(context.getBean(BeanB.class), context.getBean(BeanA.class).b);
assertSame(c, context.getBean(BeanA.class).c);
assertSame(context, context.getBean(BeanB.class).applicationContext);
}
@Test
public void individualNamedBeanWithMixedConstructorArguments() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
BeanC c = new BeanC();
context.registerBean("a", BeanA.class, c);
context.registerBean("b", BeanB.class);
context.refresh();
assertSame(context.getBean("b", BeanB.class), context.getBean("a", BeanA.class).b);
assertSame(c, context.getBean("a", BeanA.class).c);
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
}
@Test
public void getBeanByTypeRaisesNoSuchBeanDefinitionException() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
@@ -123,12 +219,11 @@ public class AnnotationConfigApplicationContextTests {
// attempt to retrieve a bean that does not exist
Class<?> targetType = Pattern.class;
try {
Object bean = context.getBean(targetType);
fail("should have thrown NoSuchBeanDefinitionException, instead got: " + bean);
context.getBean(targetType);
fail("Should have thrown NoSuchBeanDefinitionException");
}
catch (NoSuchBeanDefinitionException ex) {
assertThat(ex.getMessage(), containsString(
format("No qualifying bean of type '%s'", targetType.getName())));
assertThat(ex.getMessage(), containsString(format("No qualifying bean of type '%s'", targetType.getName())));
}
}
@@ -188,6 +283,7 @@ public class AnnotationConfigApplicationContextTests {
@Configuration
static class Config {
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
@@ -198,6 +294,7 @@ public class AnnotationConfigApplicationContextTests {
@Configuration("customConfigBeanName")
static class ConfigWithCustomName {
@Bean
public TestBean testBean() {
return new TestBean();
@@ -205,6 +302,7 @@ public class AnnotationConfigApplicationContextTests {
}
static class ConfigMissingAnnotation {
@Bean
public TestBean testBean() {
return new TestBean();
@@ -213,18 +311,26 @@ public class AnnotationConfigApplicationContextTests {
@Configuration
static class TwoTestBeanConfig {
@Bean TestBean tb1() { return new TestBean(); }
@Bean TestBean tb2() { return new TestBean(); }
@Bean TestBean tb1() {
return new TestBean();
}
@Bean TestBean tb2() {
return new TestBean();
}
}
@Configuration
static class NameConfig {
@Bean String name() { return "foo"; }
}
@Configuration
@Import(NameConfig.class)
static class AutowiredConfig {
@Autowired String autowiredName;
@Bean TestBean testBean() {
@@ -234,6 +340,27 @@ public class AnnotationConfigApplicationContextTests {
}
}
static class BeanA {
BeanB b;
BeanC c;
@Autowired public BeanA(BeanB b, BeanC c) {
this.b = b;
this.c = c;
}
}
static class BeanB {
@Autowired ApplicationContext applicationContext;
public BeanB() {
}
}
static class BeanC {}
static class UntypedFactoryBean implements FactoryBean<Object> {
@Override