-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Closed
Closed
Copy link
Labels
in: coreIssues in core modules (aop, beans, core, context, expression)Issues in core modules (aop, beans, core, context, expression)type: bugA general bugA general bug
Milestone
Description
Overview
When I was reading the source code for DefaultListableBeanFactory#determineHighestPriorityCandidate(), I found that when multiple beans have the same priority but not the highest priority, the highest priority bean cannot be obtained correctly.
Example
Consider the following scenario:
public interface IFacade {
}
@Priority(10)
@Service
public class Facade0 implements IFacade{
}
@Priority(9)
@Service
public class Facade1 implements IFacade{
}
@Priority(9)
@Service
public class Facade2 implements IFacade{
}
@Priority(8)
@Service
public class Facade3 implements IFacade{
}
@Component
public class Config {
@Autowired
private IFacade facade;
}
Proposal
I know that @Qualifier
or @Primary
can be used to handle this situation, but in this case, the highest priority bean is only Facade3
, which should be correctly injected into Config
instead of throwing an exception.
Can you consider adding the highest priority results to a List
(refer to the code below) and throwing an exception if there are multiple beans with the highest priority?
@Nullable
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
List<String> highestPriorityBeanNames = new ArrayList<>();
Integer highestPriority = null;
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if (beanInstance != null) {
Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) {
if (!highestPriorityBeanNames.isEmpty()) {
if (candidatePriority.equals(highestPriority)) {
highestPriorityBeanNames.add(candidateBeanName);
}
else if (candidatePriority < highestPriority) {
highestPriorityBeanNames.clear();
highestPriorityBeanNames.add(candidateBeanName);
highestPriority = candidatePriority;
}
}
else {
highestPriorityBeanNames.add(candidateBeanName);
highestPriority = candidatePriority;
}
}
}
}
if (highestPriorityBeanNames.size() > 1) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"Multiple beans found with the same priority ('" + highestPriority +
"') among candidates: " + candidates.keySet());
}
return highestPriorityBeanNames.isEmpty() ? null : highestPriorityBeanNames.get(0);
}
Metadata
Metadata
Assignees
Labels
in: coreIssues in core modules (aop, beans, core, context, expression)Issues in core modules (aop, beans, core, context, expression)type: bugA general bugA general bug