From e7705f4f71c3a127db0ad945ca848bd78c8fca41 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 8 Mar 2022 13:44:28 +0000 Subject: [PATCH] Improve condition message produced by @ConditionalOnSingleCandidate Closes gh-30073 --- .../condition/OnBeanCondition.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java index 756068f5b13d..ddc99827feac 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -130,13 +130,25 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM if (!matchResult.isAllMatched()) { return ConditionOutcome.noMatch(spec.message().didNotFind("any beans").atAll()); } - else if (!hasSingleAutowireCandidate(context.getBeanFactory(), matchResult.getNamesOfAllMatches(), - spec.getStrategy() == SearchStrategy.ALL)) { - return ConditionOutcome.noMatch(spec.message().didNotFind("a primary bean from beans") - .items(Style.QUOTE, matchResult.getNamesOfAllMatches())); + Set allBeans = matchResult.getNamesOfAllMatches(); + if (allBeans.size() == 1) { + matchMessage = spec.message(matchMessage).found("a single bean").items(Style.QUOTE, allBeans); + } + else { + List primaryBeans = getPrimaryBeans(context.getBeanFactory(), allBeans, + spec.getStrategy() == SearchStrategy.ALL); + if (primaryBeans.isEmpty()) { + return ConditionOutcome.noMatch( + spec.message().didNotFind("a primary bean from beans").items(Style.QUOTE, allBeans)); + } + if (primaryBeans.size() > 1) { + return ConditionOutcome + .noMatch(spec.message().found("multiple primary beans").items(Style.QUOTE, primaryBeans)); + } + matchMessage = spec.message(matchMessage) + .found("a single primary bean '" + primaryBeans.get(0) + "' from beans") + .items(Style.QUOTE, allBeans); } - matchMessage = spec.message(matchMessage).found("a primary bean from beans").items(Style.QUOTE, - matchResult.getNamesOfAllMatches()); } if (metadata.isAnnotated(ConditionalOnMissingBean.class.getName())) { Spec spec = new Spec<>(context, metadata, annotations, @@ -341,11 +353,6 @@ private void appendMessageForMatches(StringBuilder reason, Map beanNames, - boolean considerHierarchy) { - return (beanNames.size() == 1 || getPrimaryBeans(beanFactory, beanNames, considerHierarchy).size() == 1); - } - private List getPrimaryBeans(ConfigurableListableBeanFactory beanFactory, Set beanNames, boolean considerHierarchy) { List primaryBeans = new ArrayList<>();