Skip to content

Commit bb5b5d5

Browse files
committed
Revised condition override check based on method names instead of bean names
Issue: SPR-12744
1 parent 8f228d1 commit bb5b5d5

File tree

3 files changed

+50
-14
lines changed

3 files changed

+50
-14
lines changed

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ final class ConfigurationClass {
6464
private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
6565
new LinkedHashMap<ImportBeanDefinitionRegistrar, AnnotationMetadata>();
6666

67-
final Set<String> skippedBeans = new HashSet<String>();
67+
final Set<String> skippedBeanMethods = new HashSet<String>();
6868

6969

7070
/**

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,22 @@ private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationCl
184184
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
185185
ConfigurationClass configClass = beanMethod.getConfigurationClass();
186186
MethodMetadata metadata = beanMethod.getMetadata();
187-
188-
// Consider name and any aliases
189-
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
190-
List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name")));
191-
String beanName = (names.size() > 0 ? names.remove(0) : beanMethod.getMetadata().getMethodName());
187+
String methodName = metadata.getMethodName();
192188

193189
// Do we need to mark the bean as skipped by its condition?
194190
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
195-
configClass.skippedBeans.add(beanName);
191+
configClass.skippedBeanMethods.add(methodName);
196192
return;
197193
}
198-
if (configClass.skippedBeans.contains(beanName)) {
194+
if (configClass.skippedBeanMethods.contains(methodName)) {
199195
return;
200196
}
201197

198+
// Consider name and any aliases
199+
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
200+
List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name")));
201+
String beanName = (names.size() > 0 ? names.remove(0) : methodName);
202+
202203
// Register aliases even when overridden
203204
for (String alias : names) {
204205
this.registry.registerAlias(beanName, alias);
@@ -216,12 +217,12 @@ private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
216217
if (metadata.isStatic()) {
217218
// static @Bean method
218219
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
219-
beanDef.setFactoryMethodName(metadata.getMethodName());
220+
beanDef.setFactoryMethodName(methodName);
220221
}
221222
else {
222223
// instance @Bean method
223224
beanDef.setFactoryBeanName(configClass.getBeanName());
224-
beanDef.setUniqueFactoryMethodName(metadata.getMethodName());
225+
beanDef.setUniqueFactoryMethodName(methodName);
225226
}
226227
beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
227228
beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.lang.annotation.Retention;
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
23+
import java.util.Map;
2324

2425
import org.junit.Rule;
2526
import org.junit.Test;
@@ -127,7 +128,17 @@ public void conditionOnOverriddenMethodHonored() {
127128
@Test
128129
public void noConditionOnOverriddenMethodHonored() {
129130
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithBeanReactivated.class);
130-
assertEquals(1, context.getBeansOfType(ExampleBean.class).size());
131+
Map<String, ExampleBean> beans = context.getBeansOfType(ExampleBean.class);
132+
assertEquals(1, beans.size());
133+
assertEquals("baz", beans.keySet().iterator().next());
134+
}
135+
136+
@Test
137+
public void configWithAlternativeBeans() {
138+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithAlternativeBeans.class);
139+
Map<String, ExampleBean> beans = context.getBeansOfType(ExampleBean.class);
140+
assertEquals(1, beans.size());
141+
assertEquals("baz", beans.keySet().iterator().next());
131142
}
132143

133144

@@ -218,6 +229,14 @@ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
218229
}
219230
}
220231

232+
static class AlwaysCondition implements Condition {
233+
234+
@Override
235+
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
236+
return true;
237+
}
238+
}
239+
221240
@Component
222241
@Never
223242
static class NonConfigurationClass {
@@ -277,15 +296,15 @@ static class ExampleBean {
277296
}
278297

279298
@Configuration
280-
private static class ConfigWithBeanActive {
299+
static class ConfigWithBeanActive {
281300

282301
@Bean
283302
public ExampleBean baz() {
284303
return new ExampleBean();
285304
}
286305
}
287306

288-
private static class ConfigWithBeanSkipped extends ConfigWithBeanActive {
307+
static class ConfigWithBeanSkipped extends ConfigWithBeanActive {
289308

290309
@Override
291310
@Bean
@@ -295,7 +314,7 @@ public ExampleBean baz() {
295314
}
296315
}
297316

298-
private static class ConfigWithBeanReactivated extends ConfigWithBeanSkipped {
317+
static class ConfigWithBeanReactivated extends ConfigWithBeanSkipped {
299318

300319
@Override
301320
@Bean
@@ -304,4 +323,20 @@ public ExampleBean baz() {
304323
}
305324
}
306325

326+
@Configuration
327+
static class ConfigWithAlternativeBeans {
328+
329+
@Bean(name = "baz")
330+
@Conditional(AlwaysCondition.class)
331+
public ExampleBean baz1() {
332+
return new ExampleBean();
333+
}
334+
335+
@Bean(name = "baz")
336+
@Conditional(NeverCondition.class)
337+
public ExampleBean baz2() {
338+
return new ExampleBean();
339+
}
340+
}
341+
307342
}

0 commit comments

Comments
 (0)