Ignore duplicate @Priority values when determining highest priority
Prior to this commit, DefaultListableBeanFactory's determineHighestPriorityCandidate() method sometimes failed to determine the highest priority candidate if duplicate priority candidates were detected whose priority was not the highest priority in the candidate set. In addition, the bean registration order affected the outcome of the algorithm: if the highest priority was detected before other duplicate priorities were detected, the algorithm succeeded in determining the highest priority candidate. This commit addresses those shortcomings by ignoring duplicate @Priority values unless the duplication is for the highest priority encountered, in which case a NoUniqueBeanDefinitionException is still thrown to signal that multiple beans were found with the same "highest priority". Closes gh-33733
This commit is contained in:
@@ -1776,12 +1776,15 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
* @param requiredType the target dependency type to match against
|
||||
* @return the name of the candidate with the highest priority,
|
||||
* or {@code null} if none found
|
||||
* @throws NoUniqueBeanDefinitionException if multiple beans are detected with
|
||||
* the same highest priority value
|
||||
* @see #getPriority(Object)
|
||||
*/
|
||||
@Nullable
|
||||
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
|
||||
String highestPriorityBeanName = null;
|
||||
Integer highestPriority = null;
|
||||
boolean highestPriorityConflictDetected = false;
|
||||
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
|
||||
String candidateBeanName = entry.getKey();
|
||||
Object beanInstance = entry.getValue();
|
||||
@@ -1790,13 +1793,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (candidatePriority != null) {
|
||||
if (highestPriority != null) {
|
||||
if (candidatePriority.equals(highestPriority)) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
|
||||
"Multiple beans found with the same priority ('" + highestPriority +
|
||||
"') among candidates: " + candidates.keySet());
|
||||
highestPriorityConflictDetected = true;
|
||||
}
|
||||
else if (candidatePriority < highestPriority) {
|
||||
highestPriorityBeanName = candidateBeanName;
|
||||
highestPriority = candidatePriority;
|
||||
highestPriorityConflictDetected = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1806,6 +1808,13 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highestPriorityConflictDetected) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
|
||||
"Multiple beans found with the same highest priority (" + highestPriority +
|
||||
") among candidates: " + candidates.keySet());
|
||||
|
||||
}
|
||||
return highestPriorityBeanName;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user