diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java index aaf7179578..5cb5c0f3b1 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java @@ -64,7 +64,7 @@ final class ConfigurationClass { private final Map importBeanDefinitionRegistrars = new LinkedHashMap(); - final Set skippedBeans = new HashSet(); + final Set skippedBeanMethods = new HashSet(); /** diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 02f224f70e..b5926e7e3a 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -184,21 +184,22 @@ class ConfigurationClassBeanDefinitionReader { private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); - - // Consider name and any aliases - AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); - List names = new ArrayList(Arrays.asList(bean.getStringArray("name"))); - String beanName = (names.size() > 0 ? names.remove(0) : beanMethod.getMetadata().getMethodName()); + String methodName = metadata.getMethodName(); // Do we need to mark the bean as skipped by its condition? if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { - configClass.skippedBeans.add(beanName); + configClass.skippedBeanMethods.add(methodName); return; } - if (configClass.skippedBeans.contains(beanName)) { + if (configClass.skippedBeanMethods.contains(methodName)) { return; } + // Consider name and any aliases + AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); + List names = new ArrayList(Arrays.asList(bean.getStringArray("name"))); + String beanName = (names.size() > 0 ? names.remove(0) : methodName); + // Register aliases even when overridden for (String alias : names) { this.registry.registerAlias(beanName, alias); @@ -216,12 +217,12 @@ class ConfigurationClassBeanDefinitionReader { if (metadata.isStatic()) { // static @Bean method beanDef.setBeanClassName(configClass.getMetadata().getClassName()); - beanDef.setFactoryMethodName(metadata.getMethodName()); + beanDef.setFactoryMethodName(methodName); } else { // instance @Bean method beanDef.setFactoryBeanName(configClass.getBeanName()); - beanDef.setUniqueFactoryMethodName(metadata.getMethodName()); + beanDef.setUniqueFactoryMethodName(methodName); } beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java index 4ae5a2ec08..312baf1cde 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java @@ -20,6 +20,7 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.Map; import org.junit.Rule; import org.junit.Test; @@ -127,7 +128,17 @@ public class ConfigurationClassWithConditionTests { @Test public void noConditionOnOverriddenMethodHonored() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithBeanReactivated.class); - assertEquals(1, context.getBeansOfType(ExampleBean.class).size()); + Map beans = context.getBeansOfType(ExampleBean.class); + assertEquals(1, beans.size()); + assertEquals("baz", beans.keySet().iterator().next()); + } + + @Test + public void configWithAlternativeBeans() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithAlternativeBeans.class); + Map beans = context.getBeansOfType(ExampleBean.class); + assertEquals(1, beans.size()); + assertEquals("baz", beans.keySet().iterator().next()); } @@ -218,6 +229,14 @@ public class ConfigurationClassWithConditionTests { } } + static class AlwaysCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return true; + } + } + @Component @Never static class NonConfigurationClass { @@ -277,7 +296,7 @@ public class ConfigurationClassWithConditionTests { } @Configuration - private static class ConfigWithBeanActive { + static class ConfigWithBeanActive { @Bean public ExampleBean baz() { @@ -285,7 +304,7 @@ public class ConfigurationClassWithConditionTests { } } - private static class ConfigWithBeanSkipped extends ConfigWithBeanActive { + static class ConfigWithBeanSkipped extends ConfigWithBeanActive { @Override @Bean @@ -295,7 +314,7 @@ public class ConfigurationClassWithConditionTests { } } - private static class ConfigWithBeanReactivated extends ConfigWithBeanSkipped { + static class ConfigWithBeanReactivated extends ConfigWithBeanSkipped { @Override @Bean @@ -304,4 +323,20 @@ public class ConfigurationClassWithConditionTests { } } + @Configuration + static class ConfigWithAlternativeBeans { + + @Bean(name = "baz") + @Conditional(AlwaysCondition.class) + public ExampleBean baz1() { + return new ExampleBean(); + } + + @Bean(name = "baz") + @Conditional(NeverCondition.class) + public ExampleBean baz2() { + return new ExampleBean(); + } + } + }