9 changed files with 146 additions and 47 deletions
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
package org.springframework.context.annotation; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.junit.Assert.assertThat; |
||||
import static org.junit.Assert.assertTrue; |
||||
import static org.junit.Assert.fail; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; |
||||
|
||||
/** |
||||
* Tests regarding overloading and overriding of bean methods. |
||||
* Related to SPR-6618. |
||||
* |
||||
* Bean-annotated methods should be able to be overridden, just as any regular |
||||
* method. This is straightforward. |
||||
* |
||||
* Bean-annotated methods should be able to be overloaded, though supporting this |
||||
* is more subtle. Essentially, it must be unambiguous to the container which bean |
||||
* method to call. A simple way to think about this is that no one Configuration |
||||
* class may declare two bean methods with the same name. In the case of inheritance, |
||||
* the most specific subclass bean method will always be the one that is invoked. |
||||
* |
||||
* @author Chris Beams |
||||
*/ |
||||
public class BeanMethodPolymorphismTests { |
||||
|
||||
@Test |
||||
public void beanMethodOverloadingWithoutInheritance() { |
||||
@SuppressWarnings("unused") |
||||
@Configuration class Config { |
||||
@Bean String aString() { return "na"; } |
||||
@Bean String aString(Integer dependency) { return "na"; } |
||||
} |
||||
try { |
||||
new AnnotationConfigApplicationContext(Config.class); |
||||
fail("expected bean method overloading exception"); |
||||
} catch (BeanDefinitionParsingException ex) { |
||||
assertTrue(ex.getMessage(), ex.getMessage().contains("2 overloaded @Bean methods named 'aString'")); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void beanMethodOverloadingWithInheritance() { |
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SubConfig.class); |
||||
assertThat(ctx.getBean(String.class), equalTo("overloaded5")); |
||||
} |
||||
static @Configuration class SuperConfig { |
||||
@Bean String aString() { return "super"; } |
||||
} |
||||
static @Configuration class SubConfig { |
||||
@Bean Integer anInt() { return 5; } |
||||
@Bean String aString(Integer dependency) { return "overloaded"+dependency; } |
||||
} |
||||
|
||||
/** |
||||
* When inheritance is not involved, it is still possible to override a bean method from |
||||
* the container's point of view. This is not strictly 'overloading' of a method per se, |
||||
* so it's referred to here as 'shadowing' to distinguish the difference. |
||||
*/ |
||||
@Test |
||||
public void beanMethodShadowing() { |
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ShadowConfig.class); |
||||
assertThat(ctx.getBean(String.class), equalTo("shadow")); |
||||
} |
||||
@Import(SubConfig.class) |
||||
static @Configuration class ShadowConfig { |
||||
@Bean String aString() { return "shadow"; } |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue