Skip to content

Commit

Permalink
Add additional shortcut for qualifier value matching target bean name
Browse files Browse the repository at this point in the history
Closes gh-17677
See gh-28122
  • Loading branch information
jhoeller committed Feb 19, 2024
1 parent 874e61a commit a001319
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ protected boolean checkQualifier(
}
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
expectedValue instanceof String name && bdHolder.matchesName(name)) {
// Fall back on bean name (or alias) match
// Finally, check bean name (or alias) match
continue;
}
if (actualValue == null && qualifier != null) {
Expand Down Expand Up @@ -333,14 +333,28 @@ public boolean isRequired(DependencyDescriptor descriptor) {
*/
@Override
public boolean hasQualifier(DependencyDescriptor descriptor) {
for (Annotation ann : descriptor.getAnnotations()) {
if (isQualifier(ann.annotationType())) {
for (Annotation annotation : descriptor.getAnnotations()) {
if (isQualifier(annotation.annotationType())) {
return true;
}
}
return false;
}

@Override
@Nullable
public String getSuggestedName(DependencyDescriptor descriptor) {
for (Annotation annotation : descriptor.getAnnotations()) {
if (isQualifier(annotation.annotationType())) {
Object value = AnnotationUtils.getValue(annotation);
if (value instanceof String str) {
return str;
}
}
}
return null;
}

/**
* Determine whether the given dependency declares a value annotation.
* @see Value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -72,6 +72,18 @@ default boolean hasQualifier(DependencyDescriptor descriptor) {
return false;
}

/**
* Determine whether a target bean name is suggested for the given dependency
* (typically - but not necessarily - declared with a single-value qualifier).
* @param descriptor the descriptor for the target method parameter or field
* @return the qualifier value, if any
* @since 6.2
*/
@Nullable
default String getSuggestedName(DependencyDescriptor descriptor) {
return null;
}

/**
* Determine whether a default value is suggested for the given dependency.
* <p>The default implementation simply returns {@code null}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1400,9 +1400,13 @@ public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable Str
}
}

// Step 3: shortcut for declared dependency name matching target bean name
// Step 3: shortcut for declared dependency name or qualifier-suggested name matching target bean name
String dependencyName = descriptor.getDependencyName();
if (dependencyName != null && containsBean(dependencyName) &&
if (dependencyName == null || !containsBean(dependencyName)) {
String suggestedName = getAutowireCandidateResolver().getSuggestedName(descriptor);
dependencyName = (suggestedName != null && containsBean(suggestedName) ? suggestedName : null);
}
if (dependencyName != null &&
isTypeMatch(dependencyName, type) && isAutowireCandidate(dependencyName, descriptor) &&
!hasPrimaryConflict(dependencyName, type) && !isSelfReference(beanName, dependencyName)) {
if (autowiredBeanNames != null) {
Expand Down Expand Up @@ -1747,10 +1751,22 @@ protected String determineAutowireCandidate(Map<String, Object> candidates, Depe
if (primaryCandidate != null) {
return primaryCandidate;
}
// Step 2: check bean name match
for (String candidateName : candidates.keySet()) {
if (matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
// Step 2a: match bean name against declared dependency name
String dependencyName = descriptor.getDependencyName();
if (dependencyName != null) {
for (String beanName : candidates.keySet()) {
if (matchesBeanName(beanName, dependencyName)) {
return beanName;
}
}
}
// Step 2b: match bean name against qualifier-suggested name
String suggestedName = getAutowireCandidateResolver().getSuggestedName(descriptor);
if (suggestedName != null) {
for (String beanName : candidates.keySet()) {
if (matchesBeanName(beanName, suggestedName)) {
return beanName;
}
}
}
// Step 3: check highest priority candidate
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -52,6 +52,12 @@ public boolean hasQualifier(DependencyDescriptor descriptor) {
return false;
}

@Override
@Nullable
public String getSuggestedName(DependencyDescriptor descriptor) {
return null;
}

@Override
@Nullable
public Object getSuggestedValue(DependencyDescriptor descriptor) {
Expand Down

0 comments on commit a001319

Please sign in to comment.