Allow early OnBeanCondition filtering

Update `OnBeanCondition` to be an `AutoConfigurationImportFilter` and
filter out classes early.

See gh-13328
This commit is contained in:
Phillip Webb 2018-09-24 09:30:07 -04:00
parent 586507c49a
commit c2f8398c06
2 changed files with 38 additions and 2 deletions

View File

@ -34,6 +34,7 @@ import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
@ -58,7 +59,8 @@ import org.springframework.util.StringUtils;
* @author Andy Wilkinson
*/
@Order(Ordered.LOWEST_PRECEDENCE)
class OnBeanCondition extends SpringBootCondition implements ConfigurationCondition {
class OnBeanCondition extends FilteringSpringBootCondition
implements ConfigurationCondition {
/**
* Bean definition attribute name for factory beans to signal their product type (if
@ -66,6 +68,40 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit
*/
public static final String FACTORY_BEAN_OBJECT_TYPE = BeanTypeRegistry.FACTORY_BEAN_OBJECT_TYPE;
@Override
protected final ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionOutcome[] outcomes = new ConditionOutcome[autoConfigurationClasses.length];
for (int i = 0; i < outcomes.length; i++) {
String autoConfigurationClass = autoConfigurationClasses[i];
if (autoConfigurationClass != null) {
Set<String> onBeanTypes = autoConfigurationMetadata
.getSet(autoConfigurationClass, "ConditionalOnBean");
outcomes[i] = getOutcome(onBeanTypes, ConditionalOnBean.class);
if (outcomes[i] == null) {
Set<String> onSingleCandidateTypes = autoConfigurationMetadata.getSet(
autoConfigurationClass, "ConditionalOnSingleCandidate");
outcomes[i] = getOutcome(onSingleCandidateTypes,
ConditionalOnSingleCandidate.class);
}
}
}
return outcomes;
}
private ConditionOutcome getOutcome(Set<String> requiredBeanTypes,
Class<? extends Annotation> annotation) {
List<String> missing = filter(requiredBeanTypes, ClassNameFilter.MISSING,
getBeanClassLoader());
if (!missing.isEmpty()) {
ConditionMessage message = ConditionMessage.forCondition(annotation)
.didNotFind("required type", "required types")
.items(Style.QUOTE, missing);
return ConditionOutcome.noMatch(message);
}
return null;
}
@Override
public ConfigurationPhase getConfigurationPhase() {
return ConfigurationPhase.REGISTER_BEAN;
@ -337,7 +373,6 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit
.getParentBeanFactory()), beanName, considerHierarchy);
}
return null;
}
private static class BeanSearchSpec {

View File

@ -17,6 +17,7 @@ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoCo
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition
# Auto Configure