Browse Source

Revised condition override check based on method names instead of bean names

Issue: SPR-12744
pull/746/head
Juergen Hoeller 11 years ago
parent
commit
bb5b5d52ed
  1. 2
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java
  2. 19
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
  3. 43
      spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java

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

@ -64,7 +64,7 @@ final class ConfigurationClass {
private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars = private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
new LinkedHashMap<ImportBeanDefinitionRegistrar, AnnotationMetadata>(); new LinkedHashMap<ImportBeanDefinitionRegistrar, AnnotationMetadata>();
final Set<String> skippedBeans = new HashSet<String>(); final Set<String> skippedBeanMethods = new HashSet<String>();
/** /**

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

@ -184,21 +184,22 @@ class ConfigurationClassBeanDefinitionReader {
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass(); ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata(); MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
// Consider name and any aliases
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name")));
String beanName = (names.size() > 0 ? names.remove(0) : beanMethod.getMetadata().getMethodName());
// Do we need to mark the bean as skipped by its condition? // Do we need to mark the bean as skipped by its condition?
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeans.add(beanName); configClass.skippedBeanMethods.add(methodName);
return; return;
} }
if (configClass.skippedBeans.contains(beanName)) { if (configClass.skippedBeanMethods.contains(methodName)) {
return; return;
} }
// Consider name and any aliases
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name")));
String beanName = (names.size() > 0 ? names.remove(0) : methodName);
// Register aliases even when overridden // Register aliases even when overridden
for (String alias : names) { for (String alias : names) {
this.registry.registerAlias(beanName, alias); this.registry.registerAlias(beanName, alias);
@ -216,12 +217,12 @@ class ConfigurationClassBeanDefinitionReader {
if (metadata.isStatic()) { if (metadata.isStatic()) {
// static @Bean method // static @Bean method
beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setBeanClassName(configClass.getMetadata().getClassName());
beanDef.setFactoryMethodName(metadata.getMethodName()); beanDef.setFactoryMethodName(methodName);
} }
else { else {
// instance @Bean method // instance @Bean method
beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(metadata.getMethodName()); beanDef.setUniqueFactoryMethodName(methodName);
} }
beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

43
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.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.util.Map;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -127,7 +128,17 @@ public class ConfigurationClassWithConditionTests {
@Test @Test
public void noConditionOnOverriddenMethodHonored() { public void noConditionOnOverriddenMethodHonored() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithBeanReactivated.class); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigWithBeanReactivated.class);
assertEquals(1, context.getBeansOfType(ExampleBean.class).size()); Map<String, ExampleBean> 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<String, ExampleBean> 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 @Component
@Never @Never
static class NonConfigurationClass { static class NonConfigurationClass {
@ -277,7 +296,7 @@ public class ConfigurationClassWithConditionTests {
} }
@Configuration @Configuration
private static class ConfigWithBeanActive { static class ConfigWithBeanActive {
@Bean @Bean
public ExampleBean baz() { public ExampleBean baz() {
@ -285,7 +304,7 @@ public class ConfigurationClassWithConditionTests {
} }
} }
private static class ConfigWithBeanSkipped extends ConfigWithBeanActive { static class ConfigWithBeanSkipped extends ConfigWithBeanActive {
@Override @Override
@Bean @Bean
@ -295,7 +314,7 @@ public class ConfigurationClassWithConditionTests {
} }
} }
private static class ConfigWithBeanReactivated extends ConfigWithBeanSkipped { static class ConfigWithBeanReactivated extends ConfigWithBeanSkipped {
@Override @Override
@Bean @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();
}
}
} }

Loading…
Cancel
Save