16
16
17
17
package org .springframework .context .annotation ;
18
18
19
- import java .lang .annotation .Inherited ;
20
19
import java .util .List ;
21
20
22
- import org .junit .Rule ;
23
21
import org .junit .Test ;
24
- import org .junit .rules .ExpectedException ;
25
22
26
- import org .springframework .beans .factory .parsing .BeanDefinitionParsingException ;
27
23
import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
28
24
import org .springframework .beans .factory .support .RootBeanDefinition ;
29
25
34
30
* Tests regarding overloading and overriding of bean methods.
35
31
* Related to SPR-6618.
36
32
*
37
- * Bean-annotated methods should be able to be overridden, just as any regular
38
- * method. This is straightforward.
39
- *
40
- * Bean-annotated methods should be able to be overloaded, though supporting this
41
- * is more subtle. Essentially, it must be unambiguous to the container which bean
42
- * method to call. A simple way to think about this is that no one Configuration
43
- * class may declare two bean methods with the same name. In the case of inheritance,
44
- * the most specific subclass bean method will always be the one that is invoked.
45
- *
46
33
* @author Chris Beams
47
34
* @author Phillip Webb
35
+ * @author Juergen Hoeller
48
36
*/
49
- @ SuppressWarnings ("resource" )
50
37
public class BeanMethodPolymorphismTests {
51
38
52
- @ Rule
53
- public ExpectedException thrown = ExpectedException .none ();
54
-
55
-
56
39
@ Test
57
40
public void beanMethodOverloadingWithoutInheritance () {
41
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
42
+ ctx .register (ConfigWithOverloading .class );
43
+ ctx .setAllowBeanDefinitionOverriding (false );
44
+ ctx .refresh ();
45
+ assertThat (ctx .getBean (String .class ), equalTo ("regular" ));
46
+ }
58
47
59
- @ SuppressWarnings ({ "hiding" })
60
- @ Configuration class Config {
61
- @ Bean String aString () { return "na" ; }
62
- @ Bean String aString (Integer dependency ) { return "na" ; }
63
- }
48
+ @ Test
49
+ public void beanMethodOverloadingWithoutInheritanceAndExtraDependency () {
50
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
51
+ ctx .register (ConfigWithOverloading .class );
52
+ ctx .getDefaultListableBeanFactory ().registerSingleton ("anInt" , 5 );
53
+ ctx .setAllowBeanDefinitionOverriding (false );
54
+ ctx .refresh ();
55
+ assertThat (ctx .getBean (String .class ), equalTo ("overloaded5" ));
56
+ }
57
+
58
+ @ Test
59
+ public void beanMethodOverloadingWithAdditionalMetadata () {
60
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
61
+ ctx .register (ConfigWithOverloadingAndAdditionalMetadata .class );
62
+ ctx .setAllowBeanDefinitionOverriding (false );
63
+ ctx .refresh ();
64
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
65
+ assertThat (ctx .getBean (String .class ), equalTo ("regular" ));
66
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
67
+ }
64
68
65
- this .thrown .expect (BeanDefinitionParsingException .class );
66
- this .thrown .expectMessage ("overloaded @Bean methods named 'aString'" );
67
- new AnnotationConfigApplicationContext (Config .class );
69
+ @ Test
70
+ public void beanMethodOverloadingWithAdditionalMetadataButOtherMethodExecuted () {
71
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
72
+ ctx .register (ConfigWithOverloadingAndAdditionalMetadata .class );
73
+ ctx .getDefaultListableBeanFactory ().registerSingleton ("anInt" , 5 );
74
+ ctx .setAllowBeanDefinitionOverriding (false );
75
+ ctx .refresh ();
76
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
77
+ assertThat (ctx .getBean (String .class ), equalTo ("overloaded5" ));
78
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
68
79
}
69
80
70
81
@ Test
71
82
public void beanMethodOverloadingWithInheritance () {
72
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (SubConfig .class );
83
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
84
+ ctx .register (SubConfig .class );
85
+ ctx .setAllowBeanDefinitionOverriding (false );
86
+ ctx .refresh ();
87
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
73
88
assertThat (ctx .getBean (String .class ), equalTo ("overloaded5" ));
89
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
74
90
}
75
91
92
+ // SPR-11025
76
93
@ Test
77
94
public void beanMethodOverloadingWithInheritanceAndList () {
78
- // SPR-11025
79
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (SubConfigWithList .class );
95
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
96
+ ctx .register (SubConfigWithList .class );
97
+ ctx .setAllowBeanDefinitionOverriding (false );
98
+ ctx .refresh ();
99
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
80
100
assertThat (ctx .getBean (String .class ), equalTo ("overloaded5" ));
101
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
81
102
}
82
103
83
104
/**
@@ -91,11 +112,6 @@ public void beanMethodShadowing() {
91
112
assertThat (ctx .getBean (String .class ), equalTo ("shadow" ));
92
113
}
93
114
94
- /**
95
- * Tests that polymorphic Configuration classes need not explicitly redeclare the
96
- * {@link Configuration} annotation. This respects the {@link Inherited} nature
97
- * of the Configuration annotation, even though it's being detected via ASM.
98
- */
99
115
@ Test
100
116
public void beanMethodsDetectedOnSuperClass () {
101
117
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory ();
@@ -122,6 +138,36 @@ static class Config extends BaseConfig {
122
138
}
123
139
124
140
141
+ @ Configuration
142
+ static class ConfigWithOverloading {
143
+
144
+ @ Bean
145
+ String aString () {
146
+ return "regular" ;
147
+ }
148
+
149
+ @ Bean
150
+ String aString (Integer dependency ) {
151
+ return "overloaded" + dependency ;
152
+ }
153
+ }
154
+
155
+
156
+ @ Configuration
157
+ static class ConfigWithOverloadingAndAdditionalMetadata {
158
+
159
+ @ Bean @ Lazy
160
+ String aString () {
161
+ return "regular" ;
162
+ }
163
+
164
+ @ Bean
165
+ String aString (Integer dependency ) {
166
+ return "overloaded" + dependency ;
167
+ }
168
+ }
169
+
170
+
125
171
@ Configuration
126
172
static class SuperConfig {
127
173
@@ -140,7 +186,7 @@ Integer anInt() {
140
186
return 5 ;
141
187
}
142
188
143
- @ Bean
189
+ @ Bean @ Lazy
144
190
String aString (Integer dependency ) {
145
191
return "overloaded" + dependency ;
146
192
}
@@ -155,7 +201,7 @@ Integer anInt() {
155
201
return 5 ;
156
202
}
157
203
158
- @ Bean
204
+ @ Bean @ Lazy
159
205
String aString (List <Integer > dependency ) {
160
206
return "overloaded" + dependency .get (0 );
161
207
}
0 commit comments