Ignore scoped targets when finding matching beans

Fixes gh-22038
This commit is contained in:
Andy Wilkinson 2020-07-02 10:39:56 +01:00
parent 81d6751ba7
commit 21453b5016
2 changed files with 34 additions and 3 deletions

View File

@ -24,12 +24,14 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
@ -166,7 +168,13 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
for (String type : spec.getTypes()) {
Collection<String> typeMatches = getBeanNamesForType(classLoader, considerHierarchy, beanFactory, type,
parameterizedContainers);
typeMatches.removeAll(beansIgnoredByType);
Iterator<String> iterator = typeMatches.iterator();
while (iterator.hasNext()) {
String match = iterator.next();
if (beansIgnoredByType.contains(match) || ScopedProxyUtils.isScopedTarget(match)) {
iterator.remove();
}
}
if (typeMatches.isEmpty()) {
result.recordUnmatchedType(type);
}

View File

@ -22,6 +22,8 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import static org.assertj.core.api.Assertions.assertThat;
@ -50,6 +52,16 @@ class ConditionalOnSingleCandidateTests {
});
}
@Test
void singleCandidateOneScopedProxyCandidate() {
this.contextRunner
.withUserConfiguration(AlphaScopedProxyConfiguration.class, OnBeanSingleCandidateConfiguration.class)
.run((context) -> {
assertThat(context).hasBean("consumer");
assertThat(context.getBean("consumer").toString()).isEqualTo("alpha");
});
}
@Test
void singleCandidateInAncestorsOneCandidateInCurrent() {
this.contextRunner.run((parent) -> this.contextRunner
@ -138,7 +150,7 @@ class ConditionalOnSingleCandidateTests {
static class OnBeanSingleCandidateConfiguration {
@Bean
String consumer(String s) {
CharSequence consumer(CharSequence s) {
return s;
}
@ -149,7 +161,7 @@ class ConditionalOnSingleCandidateTests {
static class OnBeanSingleCandidateInAncestorsConfiguration {
@Bean
String consumer(String s) {
CharSequence consumer(CharSequence s) {
return s;
}
@ -188,6 +200,17 @@ class ConditionalOnSingleCandidateTests {
}
@Configuration(proxyBeanMethods = false)
static class AlphaScopedProxyConfiguration {
@Bean
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
String alpha() {
return "alpha";
}
}
@Configuration(proxyBeanMethods = false)
static class BravoConfiguration {