Browse Source

Revert "Ensure @Conditions consider super classes"

This reverts commit 620c16f5c7.
pull/336/merge
Phillip Webb 13 years ago
parent
commit
ced5ea2f93
  1. 15
      spring-context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java
  2. 24
      spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java
  3. 6
      spring-context/src/main/java/org/springframework/context/annotation/ConditionEvaluator.java
  4. 12
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java
  5. 13
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
  6. 39
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
  7. 49
      spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassWithConditionTests.java

15
spring-context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java

@ -134,10 +134,10 @@ public class AnnotatedBeanDefinitionReader {
} }
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) { public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
if (shouldSkip(annotatedClass)) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (conditionEvaluator.shouldSkip(abd.getMetadata())) {
return; return;
} }
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName()); abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
@ -161,17 +161,6 @@ public class AnnotatedBeanDefinitionReader {
} }
private boolean shouldSkip(Class<?> annotatedClass) {
while(annotatedClass != null) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if(conditionEvaluator.shouldSkip(abd.getMetadata())) {
return true;
}
annotatedClass = annotatedClass.getSuperclass();
}
return false;
}
/** /**
* Get the Environment from the given registry if possible, otherwise return a new * Get the Environment from the given registry if possible, otherwise return a new
* StandardEnvironment. * StandardEnvironment.

24
spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java

@ -38,7 +38,6 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReaderFactory;
@ -342,29 +341,24 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
} }
for (TypeFilter tf : this.includeFilters) { for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) { if (tf.match(metadataReader, this.metadataReaderFactory)) {
return !shouldSkip(metadataReader); return isConditionMatch(metadataReader);
} }
} }
return false; return false;
} }
private boolean shouldSkip(MetadataReader metadataReader) throws IOException { /**
* Determine whether the given class is a candidate component based on any
* {@code @Conditional} annotations.
* @param metadataReader the ASM ClassReader for the class
* @return whether the class qualifies as a candidate component
*/
private boolean isConditionMatch(MetadataReader metadataReader) {
if (this.conditionEvaluator == null) { if (this.conditionEvaluator == null) {
this.conditionEvaluator = new ConditionEvaluator(getRegistry(), this.conditionEvaluator = new ConditionEvaluator(getRegistry(),
getEnvironment(), null, null, getResourceLoader()); getEnvironment(), null, null, getResourceLoader());
} }
return !conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
while(metadataReader != null) {
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
if(this.conditionEvaluator.shouldSkip(metadata)) {
return true;
}
metadataReader = (metadata.hasSuperClass() ?
this.metadataReaderFactory.getMetadataReader(metadata.getSuperClassName())
: null);
}
return false;
} }
/** /**

6
spring-context/src/main/java/org/springframework/context/annotation/ConditionEvaluator.java

@ -50,6 +50,7 @@ class ConditionEvaluator {
*/ */
public ConditionEvaluator(BeanDefinitionRegistry registry, Environment environment, public ConditionEvaluator(BeanDefinitionRegistry registry, Environment environment,
ApplicationContext applicationContext, ClassLoader classLoader, ResourceLoader resourceLoader) { ApplicationContext applicationContext, ClassLoader classLoader, ResourceLoader resourceLoader) {
this.context = new ConditionContextImpl(registry, environment, applicationContext, classLoader, resourceLoader); this.context = new ConditionContextImpl(registry, environment, applicationContext, classLoader, resourceLoader);
} }
@ -72,6 +73,10 @@ class ConditionEvaluator {
* @return if the item should be skipped * @return if the item should be skipped
*/ */
public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) { public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) {
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
if (phase == null) { if (phase == null) {
if (metadata instanceof AnnotationMetadata && if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) { ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
@ -94,7 +99,6 @@ class ConditionEvaluator {
} }
} }
} }
return false; return false;
} }

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

@ -16,12 +16,10 @@
package org.springframework.context.annotation; package org.springframework.context.annotation;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -53,8 +51,6 @@ final class ConfigurationClass {
private final AnnotationMetadata metadata; private final AnnotationMetadata metadata;
private final List<AnnotationMetadata> metadataHierarchy = new ArrayList<AnnotationMetadata>();
private final Resource resource; private final Resource resource;
private String beanName; private String beanName;
@ -133,14 +129,6 @@ final class ConfigurationClass {
return this.metadata; return this.metadata;
} }
public List<AnnotationMetadata> getMetadataHierarchy() {
return Collections.unmodifiableList(metadataHierarchy);
}
public void addMetadataHierarchy(AnnotationMetadata metadata) {
this.metadataHierarchy.add(metadata);
}
public Resource getResource() { public Resource getResource() {
return this.resource; return this.resource;
} }

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

@ -380,22 +380,13 @@ class ConfigurationClassBeanDefinitionReader {
} }
} }
if (skip == null) { if (skip == null) {
skip = shouldSkipConsideringHierarchy(configClass); skip = conditionEvaluator.shouldSkip(configClass.getMetadata(),
ConfigurationPhase.REGISTER_BEAN);
} }
this.skipped.put(configClass, skip); this.skipped.put(configClass, skip);
} }
return skip; return skip;
} }
private boolean shouldSkipConsideringHierarchy(ConfigurationClass configClass) {
for (AnnotationMetadata metadata : configClass.getMetadataHierarchy()) {
if (conditionEvaluator.shouldSkip(metadata,
ConfigurationPhase.REGISTER_BEAN)) {
return true;
}
}
return false;
}
} }
} }

39
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

@ -183,7 +183,7 @@ class ConfigurationClassParser {
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (shouldSkip(asSourceClass(configClass), ConfigurationPhase.PARSE_CONFIGURATION)) { if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return; return;
} }
@ -201,7 +201,6 @@ class ConfigurationClassParser {
// Recursively process the configuration class and its superclass hierarchy. // Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass); SourceClass sourceClass = asSourceClass(configClass);
do { do {
configClass.addMetadataHierarchy(sourceClass.getMetadata());
sourceClass = doProcessConfigurationClass(configClass, sourceClass); sourceClass = doProcessConfigurationClass(configClass, sourceClass);
} }
while (sourceClass != null); while (sourceClass != null);
@ -231,7 +230,7 @@ class ConfigurationClassParser {
AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class); AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class);
if (componentScan != null) { if (componentScan != null) {
// the config class is annotated with @ComponentScan -> perform the scan immediately // the config class is annotated with @ComponentScan -> perform the scan immediately
if (!shouldSkip(sourceClass, ConfigurationPhase.REGISTER_BEAN)) { if (!conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
Set<BeanDefinitionHolder> scannedBeanDefinitions = Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
@ -270,7 +269,12 @@ class ConfigurationClassParser {
if (!this.knownSuperclasses.containsKey(superclass)) { if (!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass); this.knownSuperclasses.put(superclass, configClass);
// superclass found, return its annotation metadata and recurse // superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass(); try {
return sourceClass.getSuperClass();
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(ex);
}
} }
} }
@ -278,17 +282,6 @@ class ConfigurationClassParser {
return null; return null;
} }
private boolean shouldSkip(SourceClass sourceClass, ConfigurationPhase phase)
throws IOException {
while (sourceClass != null) {
if (conditionEvaluator.shouldSkip(sourceClass.getMetadata(), phase)) {
return true;
}
sourceClass = sourceClass.getSuperClass();
}
return false;
}
/** /**
* Register member (nested) classes that happen to be configuration classes themselves. * Register member (nested) classes that happen to be configuration classes themselves.
* @param sourceClass the source class to process * @param sourceClass the source class to process
@ -699,19 +692,11 @@ class ConfigurationClassParser {
return members; return members;
} }
public SourceClass getSuperClass() throws IOException { public SourceClass getSuperClass() throws IOException, ClassNotFoundException {
if (!getMetadata().hasSuperClass()) { if (this.source instanceof Class<?>) {
return null; return asSourceClass(((Class<?>) this.source).getSuperclass());
}
try {
if (this.source instanceof Class<?>) {
return asSourceClass(((Class<?>) this.source).getSuperclass());
}
return asSourceClass(((MetadataReader) this.source).getClassMetadata().getSuperClassName());
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(ex);
} }
return asSourceClass(((MetadataReader) this.source).getClassMetadata().getSuperClassName());
} }
public Set<SourceClass> getAnnotations() throws IOException, ClassNotFoundException { public Set<SourceClass> getAnnotations() throws IOException, ClassNotFoundException {

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

@ -54,21 +54,6 @@ public class ConfigurationClassWithConditionTests {
ctx.close(); ctx.close();
} }
@Test
public void conditionalOnConfiguration() throws Exception {
ctx.register(ConditionOnConfiguration.class);
ctx.refresh();
assertThat(ctx.getBeansOfType(ConditionOnConfiguration.class).size(), equalTo(0));
}
@Test
public void inheritedConditionalOnConfiguration() throws Exception {
ctx.register(InheritedConditionOnConfiguration.class);
ctx.refresh();
assertThat(ctx.getBeansOfType(ConditionOnConfiguration.class).size(), equalTo(0));
assertThat(ctx.getBeansOfType(InheritedConditionOnConfiguration.class).size(), equalTo(0));
}
@Test @Test
public void conditionalOnMissingBeanMatch() throws Exception { public void conditionalOnMissingBeanMatch() throws Exception {
ctx.register(BeanOneConfiguration.class, BeanTwoConfiguration.class); ctx.register(BeanOneConfiguration.class, BeanTwoConfiguration.class);
@ -118,14 +103,6 @@ public class ConfigurationClassWithConditionTests {
assertNull(ctx.getBean(NonConfigurationClass.class)); assertNull(ctx.getBean(NonConfigurationClass.class));
} }
@Test
public void inheritedNonConfigurationClass() throws Exception {
ctx.register(InheritedNonConfigurationClass.class);
ctx.refresh();
thrown.expect(NoSuchBeanDefinitionException.class);
assertNull(ctx.getBean(InheritedNonConfigurationClass.class));
}
@Test @Test
public void methodConditional() throws Exception { public void methodConditional() throws Exception {
ctx.register(ConditionOnMethodConfiguration.class); ctx.register(ConditionOnMethodConfiguration.class);
@ -141,13 +118,6 @@ public class ConfigurationClassWithConditionTests {
ctx.refresh(); ctx.refresh();
} }
@Test
public void inheritedImportsNotCreated() throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(InheritedImportsNotCreated.class);
ctx.refresh();
}
@Test @Test
public void importsNotLoaded() throws Exception { public void importsNotLoaded() throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@ -258,10 +228,6 @@ public class ConfigurationClassWithConditionTests {
static class NonConfigurationClass { static class NonConfigurationClass {
} }
@Component
static class InheritedNonConfigurationClass extends NonConfigurationClass {
}
@Configuration @Configuration
static class ConditionOnMethodConfiguration { static class ConditionOnMethodConfiguration {
@ -281,21 +247,6 @@ public class ConfigurationClassWithConditionTests {
} }
} }
@Configuration
@Never
static class ConditionOnConfiguration {
}
@Configuration
static class InheritedConditionOnConfiguration extends ConditionOnConfiguration {
}
@Import({ ConfigurationNotCreated.class, RegistrarNotCreated.class, ImportSelectorNotCreated.class })
static class InheritedImportsNotCreated extends ConditionOnConfiguration {
}
@Configuration @Configuration
static class ConfigurationNotCreated { static class ConfigurationNotCreated {
static { static {

Loading…
Cancel
Save