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
21
import org .junit .Rule ;
23
22
import org .junit .Test ;
24
23
import org .junit .rules .ExpectedException ;
25
24
26
25
import org .springframework .beans .factory .parsing .BeanDefinitionParsingException ;
27
- import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
28
- import org .springframework .beans .factory .support .RootBeanDefinition ;
29
26
30
27
import static org .hamcrest .CoreMatchers .*;
31
28
import static org .junit .Assert .*;
34
31
* Tests regarding overloading and overriding of bean methods.
35
32
* Related to SPR-6618.
36
33
*
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
34
* @author Chris Beams
47
35
* @author Phillip Webb
36
+ * @author Juergen Hoeller
48
37
*/
49
- @ SuppressWarnings ("resource" )
50
38
public class BeanMethodPolymorphismTests {
51
39
52
40
@ Rule
53
41
public ExpectedException thrown = ExpectedException .none ();
54
42
55
43
44
+ @ Test
45
+ public void beanMethodDetectedOnSuperClass () {
46
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (Config .class );
47
+ ctx .getBean ("testBean" , TestBean .class );
48
+ }
49
+
50
+ @ Test
51
+ public void beanMethodOverriding () {
52
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
53
+ ctx .register (OverridingConfig .class );
54
+ ctx .setAllowBeanDefinitionOverriding (false );
55
+ ctx .refresh ();
56
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("testBean" ));
57
+ assertEquals ("overridden" , ctx .getBean ("testBean" , TestBean .class ).toString ());
58
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("testBean" ));
59
+ }
60
+
56
61
@ Test
57
62
public void beanMethodOverloadingWithoutInheritance () {
58
63
@@ -69,15 +74,25 @@ public void beanMethodOverloadingWithoutInheritance() {
69
74
70
75
@ Test
71
76
public void beanMethodOverloadingWithInheritance () {
72
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (SubConfig .class );
77
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
78
+ ctx .register (SubConfig .class );
79
+ ctx .setAllowBeanDefinitionOverriding (false );
80
+ ctx .refresh ();
81
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
73
82
assertThat (ctx .getBean (String .class ), equalTo ("overloaded5" ));
83
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
74
84
}
75
85
86
+ // SPR-11025
76
87
@ Test
77
88
public void beanMethodOverloadingWithInheritanceAndList () {
78
- // SPR-11025
79
- AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (SubConfigWithList .class );
89
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
90
+ ctx .register (SubConfigWithList .class );
91
+ ctx .setAllowBeanDefinitionOverriding (false );
92
+ ctx .refresh ();
93
+ assertFalse (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
80
94
assertThat (ctx .getBean (String .class ), equalTo ("overloaded5" ));
95
+ assertTrue (ctx .getDefaultListableBeanFactory ().containsSingleton ("aString" ));
81
96
}
82
97
83
98
/**
@@ -91,20 +106,6 @@ public void beanMethodShadowing() {
91
106
assertThat (ctx .getBean (String .class ), equalTo ("shadow" ));
92
107
}
93
108
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
- @ Test
100
- public void beanMethodsDetectedOnSuperClass () {
101
- DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory ();
102
- beanFactory .registerBeanDefinition ("config" , new RootBeanDefinition (Config .class ));
103
- ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor ();
104
- pp .postProcessBeanFactory (beanFactory );
105
- beanFactory .getBean ("testBean" , TestBean .class );
106
- }
107
-
108
109
109
110
@ Configuration
110
111
static class BaseConfig {
@@ -113,7 +114,6 @@ static class BaseConfig {
113
114
public TestBean testBean () {
114
115
return new TestBean ();
115
116
}
116
-
117
117
}
118
118
119
119
@@ -122,6 +122,22 @@ static class Config extends BaseConfig {
122
122
}
123
123
124
124
125
+ @ Configuration
126
+ static class OverridingConfig extends BaseConfig {
127
+
128
+ @ Bean @ Lazy
129
+ @ Override
130
+ public TestBean testBean () {
131
+ return new TestBean () {
132
+ @ Override
133
+ public String toString () {
134
+ return "overridden" ;
135
+ }
136
+ };
137
+ }
138
+ }
139
+
140
+
125
141
@ Configuration
126
142
static class SuperConfig {
127
143
@@ -140,7 +156,7 @@ Integer anInt() {
140
156
return 5 ;
141
157
}
142
158
143
- @ Bean
159
+ @ Bean @ Lazy
144
160
String aString (Integer dependency ) {
145
161
return "overloaded" + dependency ;
146
162
}
@@ -155,7 +171,7 @@ Integer anInt() {
155
171
return 5 ;
156
172
}
157
173
158
- @ Bean
174
+ @ Bean @ Lazy
159
175
String aString (List <Integer > dependency ) {
160
176
return "overloaded" + dependency .get (0 );
161
177
}
0 commit comments