Collection injection may refer back to factory methods on same bean again

Issue: SPR-14996
(cherry picked from commit 547b963)
This commit is contained in:
Juergen Hoeller
2016-12-09 23:09:10 +01:00
parent 5115c61b03
commit 4571975414

View File

@@ -1147,7 +1147,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (type.isArray()) {
Class<?> componentType = type.getComponentType();
Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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);
}
}