From 4571975414ffa497582f1d549a0a282277c88616 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 9 Dec 2016 23:09:10 +0100 Subject: [PATCH] Collection injection may refer back to factory methods on same bean again Issue: SPR-14996 (cherry picked from commit 547b963) --- .../support/DefaultListableBeanFactory.java | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 28ce98f01a..8344849988 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -1147,7 +1147,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (type.isArray()) { Class componentType = type.getComponentType(); Map matchingBeans = findAutowireCandidates(beanName, componentType, - new MultiElementDependencyDescriptor(descriptor)); + new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } @@ -1167,7 +1167,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto return null; } Map matchingBeans = findAutowireCandidates(beanName, elementType, - new MultiElementDependencyDescriptor(descriptor)); + new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } @@ -1191,7 +1191,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto return null; } Map matchingBeans = findAutowireCandidates(beanName, valueType, - new MultiElementDependencyDescriptor(descriptor)); + new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } @@ -1258,25 +1258,27 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } } } - for (String candidateName : candidateNames) { - if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) { - addCandidateEntry(result, candidateName, descriptor, requiredType); + for (String candidate : candidateNames) { + if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { + addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { // Consider fallback matches if the first pass failed to find anything... DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); - for (String candidateName : candidateNames) { - if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, fallbackDescriptor)) { - addCandidateEntry(result, candidateName, descriptor, requiredType); + for (String candidate : candidateNames) { + if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { + addCandidateEntry(result, candidate, descriptor, requiredType); } } - if (result.isEmpty() && !(descriptor instanceof MultiElementDependencyDescriptor)) { + if (result.isEmpty()) { // Consider self references as a final pass... - // but not as collection elements, just for direct dependency declarations. - for (String candidateName : candidateNames) { - if (isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, fallbackDescriptor)) { - addCandidateEntry(result, candidateName, descriptor, requiredType); + // but in the case of a dependency collection, not the very same bean itself. + for (String candidate : candidateNames) { + if (isSelfReference(beanName, candidate) && + (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && + isAutowireCandidate(candidate, fallbackDescriptor)) { + addCandidateEntry(result, candidate, descriptor, requiredType); } } } @@ -1291,7 +1293,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto private void addCandidateEntry(Map candidates, String candidateName, DependencyDescriptor descriptor, Class requiredType) { - if (descriptor instanceof MultiElementDependencyDescriptor || containsSingleton(candidateName)) { + if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this)); } else { @@ -1745,9 +1747,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } - private static class MultiElementDependencyDescriptor extends NestedDependencyDescriptor { + private static class MultiElementDescriptor extends NestedDependencyDescriptor { - public MultiElementDependencyDescriptor(DependencyDescriptor original) { + public MultiElementDescriptor(DependencyDescriptor original) { super(original); } }