Skip to content

Commit c2f8398

Browse files
committed
Allow early OnBeanCondition filtering
Update `OnBeanCondition` to be an `AutoConfigurationImportFilter` and filter out classes early. See gh-13328
1 parent 586507c commit c2f8398

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.beans.factory.ListableBeanFactory;
3535
import org.springframework.beans.factory.config.BeanDefinition;
3636
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
37+
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
3738
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style;
3839
import org.springframework.context.annotation.Bean;
3940
import org.springframework.context.annotation.Condition;
@@ -58,14 +59,49 @@
5859
* @author Andy Wilkinson
5960
*/
6061
@Order(Ordered.LOWEST_PRECEDENCE)
61-
class OnBeanCondition extends SpringBootCondition implements ConfigurationCondition {
62+
class OnBeanCondition extends FilteringSpringBootCondition
63+
implements ConfigurationCondition {
6264

6365
/**
6466
* Bean definition attribute name for factory beans to signal their product type (if
6567
* known and it can't be deduced from the factory bean class).
6668
*/
6769
public static final String FACTORY_BEAN_OBJECT_TYPE = BeanTypeRegistry.FACTORY_BEAN_OBJECT_TYPE;
6870

71+
@Override
72+
protected final ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
73+
AutoConfigurationMetadata autoConfigurationMetadata) {
74+
ConditionOutcome[] outcomes = new ConditionOutcome[autoConfigurationClasses.length];
75+
for (int i = 0; i < outcomes.length; i++) {
76+
String autoConfigurationClass = autoConfigurationClasses[i];
77+
if (autoConfigurationClass != null) {
78+
Set<String> onBeanTypes = autoConfigurationMetadata
79+
.getSet(autoConfigurationClass, "ConditionalOnBean");
80+
outcomes[i] = getOutcome(onBeanTypes, ConditionalOnBean.class);
81+
if (outcomes[i] == null) {
82+
Set<String> onSingleCandidateTypes = autoConfigurationMetadata.getSet(
83+
autoConfigurationClass, "ConditionalOnSingleCandidate");
84+
outcomes[i] = getOutcome(onSingleCandidateTypes,
85+
ConditionalOnSingleCandidate.class);
86+
}
87+
}
88+
}
89+
return outcomes;
90+
}
91+
92+
private ConditionOutcome getOutcome(Set<String> requiredBeanTypes,
93+
Class<? extends Annotation> annotation) {
94+
List<String> missing = filter(requiredBeanTypes, ClassNameFilter.MISSING,
95+
getBeanClassLoader());
96+
if (!missing.isEmpty()) {
97+
ConditionMessage message = ConditionMessage.forCondition(annotation)
98+
.didNotFind("required type", "required types")
99+
.items(Style.QUOTE, missing);
100+
return ConditionOutcome.noMatch(message);
101+
}
102+
return null;
103+
}
104+
69105
@Override
70106
public ConfigurationPhase getConfigurationPhase() {
71107
return ConfigurationPhase.REGISTER_BEAN;
@@ -337,7 +373,6 @@ private BeanDefinition findBeanDefinition(ConfigurableListableBeanFactory beanFa
337373
.getParentBeanFactory()), beanName, considerHierarchy);
338374
}
339375
return null;
340-
341376
}
342377

343378
private static class BeanSearchSpec {

spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoCo
1717

1818
# Auto Configuration Import Filters
1919
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
20+
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
2021
org.springframework.boot.autoconfigure.condition.OnClassCondition
2122

2223
# Auto Configure

0 commit comments

Comments
 (0)