Use the field name as a fallback qualifier for Bean Overriding

This commit harmonizes how a candidate bean definition is determined
for overriding using `@TestBean`, `@MockitoBean`, and `@MockitoSpyBean`.

Previously, a qualifier was necessary even if the name of the annotated
field matches the name of a candidate. After this commit, such candidate
will be picked up transparently, the same it is done for regular
autowiring.

This commit also reviews the documentation of the feature as considering
the field means that its name is taken into account to compute a cache
key if by-type lookup is requested.

Closes gh-32939
This commit is contained in:
Stéphane Nicoll
2024-06-10 18:07:36 +02:00
parent 4c7374797e
commit 28f62abda4
10 changed files with 363 additions and 101 deletions

View File

@@ -259,6 +259,13 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
else {
beans.removeIf(ScopedProxyUtils::isScopedTarget);
}
// In case of multiple matches, last resort fallback on the field's name
if (beans.size() > 1) {
String fieldName = metadata.getField().getName();
if (beans.contains(fieldName)) {
return Set.of(fieldName);
}
}
return beans;
}

View File

@@ -167,16 +167,24 @@ public abstract class OverrideMetadata {
return false;
}
OverrideMetadata that = (OverrideMetadata) obj;
return Objects.equals(this.beanType.getType(), that.beanType.getType()) &&
Objects.equals(this.beanName, that.beanName) &&
Objects.equals(this.strategy, that.strategy) &&
if (!Objects.equals(this.beanType.getType(), that.beanType.getType()) ||
!Objects.equals(this.beanName, that.beanName) ||
!Objects.equals(this.strategy, that.strategy)) {
return false;
}
if (this.beanName != null) {
return true;
}
// by type lookup
return Objects.equals(this.field.getName(), that.field.getName()) &&
Arrays.equals(this.field.getAnnotations(), that.field.getAnnotations());
}
@Override
public int hashCode() {
return Objects.hash(this.beanType.getType(), this.beanName, this.strategy,
Arrays.hashCode(this.field.getAnnotations()));
int hash = Objects.hash(this.beanType.getType(), this.beanName, this.strategy);
return (this.beanName != null ? hash : hash +
Objects.hash(this.field.getName(), Arrays.hashCode(this.field.getAnnotations())));
}
@Override