Commit 21453b50 authored by Andy Wilkinson's avatar Andy Wilkinson

Ignore scoped targets when finding matching beans

Fixes gh-22038
parent 81d6751b
...@@ -24,12 +24,14 @@ import java.util.Collection; ...@@ -24,12 +24,14 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory; import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
...@@ -166,7 +168,13 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat ...@@ -166,7 +168,13 @@ class OnBeanCondition extends FilteringSpringBootCondition implements Configurat
for (String type : spec.getTypes()) { for (String type : spec.getTypes()) {
Collection<String> typeMatches = getBeanNamesForType(classLoader, considerHierarchy, beanFactory, type, Collection<String> typeMatches = getBeanNamesForType(classLoader, considerHierarchy, beanFactory, type,
parameterizedContainers); 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()) { if (typeMatches.isEmpty()) {
result.recordUnmatchedType(type); result.recordUnmatchedType(type);
} }
......
...@@ -22,6 +22,8 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; ...@@ -22,6 +22,8 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; 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; import static org.assertj.core.api.Assertions.assertThat;
...@@ -50,6 +52,16 @@ class ConditionalOnSingleCandidateTests { ...@@ -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 @Test
void singleCandidateInAncestorsOneCandidateInCurrent() { void singleCandidateInAncestorsOneCandidateInCurrent() {
this.contextRunner.run((parent) -> this.contextRunner this.contextRunner.run((parent) -> this.contextRunner
...@@ -138,7 +150,7 @@ class ConditionalOnSingleCandidateTests { ...@@ -138,7 +150,7 @@ class ConditionalOnSingleCandidateTests {
static class OnBeanSingleCandidateConfiguration { static class OnBeanSingleCandidateConfiguration {
@Bean @Bean
String consumer(String s) { CharSequence consumer(CharSequence s) {
return s; return s;
} }
...@@ -149,7 +161,7 @@ class ConditionalOnSingleCandidateTests { ...@@ -149,7 +161,7 @@ class ConditionalOnSingleCandidateTests {
static class OnBeanSingleCandidateInAncestorsConfiguration { static class OnBeanSingleCandidateInAncestorsConfiguration {
@Bean @Bean
String consumer(String s) { CharSequence consumer(CharSequence s) {
return s; return s;
} }
...@@ -188,6 +200,17 @@ class ConditionalOnSingleCandidateTests { ...@@ -188,6 +200,17 @@ class ConditionalOnSingleCandidateTests {
} }
@Configuration(proxyBeanMethods = false)
static class AlphaScopedProxyConfiguration {
@Bean
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
String alpha() {
return "alpha";
}
}
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
static class BravoConfiguration { static class BravoConfiguration {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment