diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 7b406d6c9115..f9c204d4225f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -111,7 +111,7 @@ class ConfigurationClassParser { private static final PropertySourceFactory DEFAULT_PROPERTY_SOURCE_FACTORY = new DefaultPropertySourceFactory(); - private static final Predicate DEFAULT_CANDIDATE_FILTER = className -> + private static final Predicate DEFAULT_EXCLUSION_FILTER = className -> (className.startsWith("java.lang.annotation.") || className.startsWith("org.springframework.stereotype.")); private static final Comparator DEFERRED_IMPORT_COMPARATOR = @@ -195,15 +195,15 @@ else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).h protected final void parse(@Nullable String className, String beanName) throws IOException { Assert.notNull(className, "No bean class name for configuration class bean definition"); MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className); - processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_CANDIDATE_FILTER); + processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER); } protected final void parse(Class clazz, String beanName) throws IOException { - processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_CANDIDATE_FILTER); + processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER); } protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { - processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_CANDIDATE_FILTER); + processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER); } /** @@ -550,7 +550,7 @@ private void collectImports(SourceClass sourceClass, Set imports, S } private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, - Collection importCandidates, Predicate candidateFilter, + Collection importCandidates, Predicate exclusionFilter, boolean checkForCircularImports) { if (importCandidates.isEmpty()) { @@ -569,17 +569,17 @@ private void processImports(ConfigurationClass configClass, SourceClass currentS Class candidateClass = candidate.loadClass(); ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class, this.environment, this.resourceLoader, this.registry); - Predicate selectorFilter = selector.getCandidateFilter(); + Predicate selectorFilter = selector.getExclusionFilter(); if (selectorFilter != null) { - candidateFilter = candidateFilter.or(selectorFilter); + exclusionFilter = exclusionFilter.or(selectorFilter); } if (selector instanceof DeferredImportSelector) { this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector); } else { String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); - Collection importSourceClasses = asSourceClasses(importClassNames, candidateFilter); - processImports(configClass, currentSourceClass, importSourceClasses, candidateFilter, false); + Collection importSourceClasses = asSourceClasses(importClassNames, exclusionFilter); + processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false); } } else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { @@ -596,7 +596,7 @@ else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { // process it as an @Configuration class this.importStack.registerImport( currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); - processConfigurationClass(candidate.asConfigClass(configClass), candidateFilter); + processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter); } } } @@ -804,13 +804,13 @@ public void register(DeferredImportSelectorHolder deferredImport) { public void processGroupImports() { for (DeferredImportSelectorGrouping grouping : this.groupings.values()) { - Predicate candidateFilter = grouping.getCandidateFilter(); + Predicate exclusionFilter = grouping.getCandidateFilter(); grouping.getImports().forEach(entry -> { ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata()); try { - processImports(configurationClass, asSourceClass(configurationClass, candidateFilter), - Collections.singleton(asSourceClass(entry.getImportClassName(), candidateFilter)), - candidateFilter, false); + processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter), + Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)), + exclusionFilter, false); } catch (BeanDefinitionStoreException ex) { throw ex; @@ -886,9 +886,9 @@ public Iterable getImports() { } public Predicate getCandidateFilter() { - Predicate mergedFilter = DEFAULT_CANDIDATE_FILTER; + Predicate mergedFilter = DEFAULT_EXCLUSION_FILTER; for (DeferredImportSelectorHolder deferredImport : this.deferredImports) { - Predicate selectorFilter = deferredImport.getImportSelector().getCandidateFilter(); + Predicate selectorFilter = deferredImport.getImportSelector().getExclusionFilter(); if (selectorFilter != null) { mergedFilter = mergedFilter.or(selectorFilter); } @@ -976,7 +976,7 @@ public Collection getMemberClasses() throws IOException { Class[] declaredClasses = sourceClass.getDeclaredClasses(); List members = new ArrayList<>(declaredClasses.length); for (Class declaredClass : declaredClasses) { - members.add(asSourceClass(declaredClass, DEFAULT_CANDIDATE_FILTER)); + members.add(asSourceClass(declaredClass, DEFAULT_EXCLUSION_FILTER)); } return members; } @@ -993,7 +993,7 @@ public Collection getMemberClasses() throws IOException { List members = new ArrayList<>(memberClassNames.length); for (String memberClassName : memberClassNames) { try { - members.add(asSourceClass(memberClassName, DEFAULT_CANDIDATE_FILTER)); + members.add(asSourceClass(memberClassName, DEFAULT_EXCLUSION_FILTER)); } catch (IOException ex) { // Let's skip it if it's not resolvable - we're just looking for candidates @@ -1008,10 +1008,10 @@ public Collection getMemberClasses() throws IOException { public SourceClass getSuperClass() throws IOException { if (this.source instanceof Class) { - return asSourceClass(((Class) this.source).getSuperclass(), DEFAULT_CANDIDATE_FILTER); + return asSourceClass(((Class) this.source).getSuperclass(), DEFAULT_EXCLUSION_FILTER); } return asSourceClass( - ((MetadataReader) this.source).getClassMetadata().getSuperClassName(), DEFAULT_CANDIDATE_FILTER); + ((MetadataReader) this.source).getClassMetadata().getSuperClassName(), DEFAULT_EXCLUSION_FILTER); } public Set getInterfaces() throws IOException { @@ -1019,12 +1019,12 @@ public Set getInterfaces() throws IOException { if (this.source instanceof Class) { Class sourceClass = (Class) this.source; for (Class ifcClass : sourceClass.getInterfaces()) { - result.add(asSourceClass(ifcClass, DEFAULT_CANDIDATE_FILTER)); + result.add(asSourceClass(ifcClass, DEFAULT_EXCLUSION_FILTER)); } } else { for (String className : this.metadata.getInterfaceNames()) { - result.add(asSourceClass(className, DEFAULT_CANDIDATE_FILTER)); + result.add(asSourceClass(className, DEFAULT_EXCLUSION_FILTER)); } } return result; @@ -1038,7 +1038,7 @@ public Set getAnnotations() { Class annType = ann.annotationType(); if (!annType.getName().startsWith("java")) { try { - result.add(asSourceClass(annType, DEFAULT_CANDIDATE_FILTER)); + result.add(asSourceClass(annType, DEFAULT_EXCLUSION_FILTER)); } catch (Throwable ex) { // An annotation not present on the classpath is being ignored @@ -1080,7 +1080,7 @@ private SourceClass getRelated(String className) throws IOException { if (this.source instanceof Class) { try { Class clazz = ClassUtils.forName(className, ((Class) this.source).getClassLoader()); - return asSourceClass(clazz, DEFAULT_CANDIDATE_FILTER); + return asSourceClass(clazz, DEFAULT_EXCLUSION_FILTER); } catch (ClassNotFoundException ex) { // Ignore -> fall back to ASM next, except for core java types. @@ -1090,7 +1090,7 @@ private SourceClass getRelated(String className) throws IOException { return new SourceClass(metadataReaderFactory.getMetadataReader(className)); } } - return asSourceClass(className, DEFAULT_CANDIDATE_FILTER); + return asSourceClass(className, DEFAULT_EXCLUSION_FILTER); } @Override diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java b/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java index df4fd0436ae4..7ae3423ec596 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ImportSelector.java @@ -68,16 +68,17 @@ public interface ImportSelector { String[] selectImports(AnnotationMetadata importingClassMetadata); /** - * Return a predicate for filtering candidate classes, to be transitively - * applied to all candidate classes found through this selector's imports. - *

If this predicate returns {@code true} for a given class name, - * said class will not be considered as a configuration class, - * bypassing class loading as well as metadata introspection. - * @return the filter predicate, or {@code null} if none + * Return a predicate for excluding classes from the import candidates, to be + * transitively applied to all classes found through this selector's imports. + *

If this predicate returns {@code true} for a given fully-qualified + * class name, said class will not be considered as an imported configuration + * class, bypassing class file loading as well as metadata introspection. + * @return the filter predicate for fully-qualified candidate class names + * of transitively imported configuration classes, or {@code null} if none * @since 5.2.4 */ @Nullable - default Predicate getCandidateFilter() { + default Predicate getExclusionFilter() { return null; } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ImportSelectorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ImportSelectorTests.java index b13682f786fa..f310720b6522 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ImportSelectorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ImportSelectorTests.java @@ -369,7 +369,7 @@ public String[] selectImports(AnnotationMetadata importingClassMetadata) { @Override @Nullable - public Predicate getCandidateFilter() { + public Predicate getExclusionFilter() { return className -> className.endsWith("ImportedSelector1"); } }