Fix qualifier resolution for aliased name against parent factory
Backport Bot / build (push) Waiting to run
Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run
Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run
Details
Backport Bot / build (push) Waiting to run
Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run
Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run
Details
Closes gh-34644
This commit is contained in:
parent
d8f8e76791
commit
37fb79e8ff
|
@ -895,7 +895,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
String bdName = transformedBeanName(beanName);
|
||||
if (containsBeanDefinition(bdName)) {
|
||||
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver);
|
||||
}
|
||||
|
@ -929,7 +929,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
|
||||
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
|
||||
|
||||
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
|
||||
String bdName = transformedBeanName(beanName);
|
||||
resolveBeanClass(mbd, bdName);
|
||||
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
|
||||
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
|
@ -21,12 +21,13 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
@ -43,14 +44,17 @@ class QualifierAnnotationAutowireBeanFactoryTests {
|
|||
|
||||
private static final String MARK = "mark";
|
||||
|
||||
private final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
void testAutowireCandidateDefaultWithIrrelevantDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(Person.class, cavs, null);
|
||||
lbf.registerBeanDefinition(JUERGEN, rbd);
|
||||
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN,
|
||||
new DependencyDescriptor(Person.class.getDeclaredField("name"), false))).isTrue();
|
||||
|
@ -60,12 +64,12 @@ class QualifierAnnotationAutowireBeanFactoryTests {
|
|||
|
||||
@Test
|
||||
void testAutowireCandidateExplicitlyFalseWithIrrelevantDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(Person.class, cavs, null);
|
||||
rbd.setAutowireCandidate(false);
|
||||
lbf.registerBeanDefinition(JUERGEN, rbd);
|
||||
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isFalse();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN,
|
||||
new DependencyDescriptor(Person.class.getDeclaredField("name"), false))).isFalse();
|
||||
|
@ -73,44 +77,46 @@ class QualifierAnnotationAutowireBeanFactoryTests {
|
|||
new DependencyDescriptor(Person.class.getDeclaredField("name"), true))).isFalse();
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
void testAutowireCandidateWithFieldDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
|
||||
ConstructorArgumentValues cavs1 = new ConstructorArgumentValues();
|
||||
cavs1.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition person1 = new RootBeanDefinition(Person.class, cavs1, null);
|
||||
person1.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
|
||||
lbf.registerBeanDefinition(JUERGEN, person1);
|
||||
|
||||
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
|
||||
cavs2.addGenericArgumentValue(MARK);
|
||||
RootBeanDefinition person2 = new RootBeanDefinition(Person.class, cavs2, null);
|
||||
lbf.registerBeanDefinition(MARK, person2);
|
||||
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(
|
||||
QualifiedTestBean.class.getDeclaredField("qualified"), false);
|
||||
DependencyDescriptor nonqualifiedDescriptor = new DependencyDescriptor(
|
||||
QualifiedTestBean.class.getDeclaredField("nonqualified"), false);
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, nonqualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, nonqualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, qualifiedDescriptor)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutowireCandidateExplicitlyFalseWithFieldDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition person = new RootBeanDefinition(Person.class, cavs, null);
|
||||
person.setAutowireCandidate(false);
|
||||
person.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
|
||||
lbf.registerBeanDefinition(JUERGEN, person);
|
||||
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(
|
||||
QualifiedTestBean.class.getDeclaredField("qualified"), false);
|
||||
DependencyDescriptor nonqualifiedDescriptor = new DependencyDescriptor(
|
||||
QualifiedTestBean.class.getDeclaredField("nonqualified"), false);
|
||||
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isFalse();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, nonqualifiedDescriptor)).isFalse();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isFalse();
|
||||
|
@ -118,56 +124,61 @@ class QualifierAnnotationAutowireBeanFactoryTests {
|
|||
|
||||
@Test
|
||||
void testAutowireCandidateWithShortClassName() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition person = new RootBeanDefinition(Person.class, cavs, null);
|
||||
person.addQualifier(new AutowireCandidateQualifier(ClassUtils.getShortName(TestQualifier.class)));
|
||||
lbf.registerBeanDefinition(JUERGEN, person);
|
||||
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(
|
||||
QualifiedTestBean.class.getDeclaredField("qualified"), false);
|
||||
DependencyDescriptor nonqualifiedDescriptor = new DependencyDescriptor(
|
||||
QualifiedTestBean.class.getDeclaredField("nonqualified"), false);
|
||||
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, nonqualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue();
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
void testAutowireCandidateWithConstructorDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
|
||||
ConstructorArgumentValues cavs1 = new ConstructorArgumentValues();
|
||||
cavs1.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition person1 = new RootBeanDefinition(Person.class, cavs1, null);
|
||||
person1.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
|
||||
lbf.registerBeanDefinition(JUERGEN, person1);
|
||||
|
||||
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
|
||||
cavs2.addGenericArgumentValue(MARK);
|
||||
RootBeanDefinition person2 = new RootBeanDefinition(Person.class, cavs2, null);
|
||||
lbf.registerBeanDefinition(MARK, person2);
|
||||
|
||||
MethodParameter param = new MethodParameter(QualifiedTestBean.class.getDeclaredConstructor(Person.class), 0);
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(param, false);
|
||||
param.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
|
||||
assertThat(param.getParameterName()).isEqualTo("tpb");
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, qualifiedDescriptor)).isFalse();
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
void testAutowireCandidateWithMethodDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
lbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
|
||||
ConstructorArgumentValues cavs1 = new ConstructorArgumentValues();
|
||||
cavs1.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition person1 = new RootBeanDefinition(Person.class, cavs1, null);
|
||||
person1.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
|
||||
lbf.registerBeanDefinition(JUERGEN, person1);
|
||||
|
||||
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
|
||||
cavs2.addGenericArgumentValue(MARK);
|
||||
RootBeanDefinition person2 = new RootBeanDefinition(Person.class, cavs2, null);
|
||||
lbf.registerBeanDefinition(MARK, person2);
|
||||
|
||||
MethodParameter qualifiedParam =
|
||||
new MethodParameter(QualifiedTestBean.class.getDeclaredMethod("autowireQualified", Person.class), 0);
|
||||
MethodParameter nonqualifiedParam =
|
||||
|
@ -175,37 +186,70 @@ class QualifierAnnotationAutowireBeanFactoryTests {
|
|||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(qualifiedParam, false);
|
||||
DependencyDescriptor nonqualifiedDescriptor = new DependencyDescriptor(nonqualifiedParam, false);
|
||||
qualifiedParam.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
assertThat(qualifiedParam.getParameterName()).isEqualTo("tpb");
|
||||
nonqualifiedParam.initParameterNameDiscovery(new DefaultParameterNameDiscoverer());
|
||||
|
||||
assertThat(qualifiedParam.getParameterName()).isEqualTo("tpb");
|
||||
assertThat(nonqualifiedParam.getParameterName()).isEqualTo("tpb");
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, nonqualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, null)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, nonqualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, qualifiedDescriptor)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutowireCandidateWithMultipleCandidatesDescriptor() throws Exception {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
ConstructorArgumentValues cavs1 = new ConstructorArgumentValues();
|
||||
cavs1.addGenericArgumentValue(JUERGEN);
|
||||
RootBeanDefinition person1 = new RootBeanDefinition(Person.class, cavs1, null);
|
||||
person1.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
|
||||
lbf.registerBeanDefinition(JUERGEN, person1);
|
||||
|
||||
ConstructorArgumentValues cavs2 = new ConstructorArgumentValues();
|
||||
cavs2.addGenericArgumentValue(MARK);
|
||||
RootBeanDefinition person2 = new RootBeanDefinition(Person.class, cavs2, null);
|
||||
person2.addQualifier(new AutowireCandidateQualifier(TestQualifier.class));
|
||||
lbf.registerBeanDefinition(MARK, person2);
|
||||
|
||||
DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(
|
||||
new MethodParameter(QualifiedTestBean.class.getDeclaredConstructor(Person.class), 0),
|
||||
false);
|
||||
|
||||
assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue();
|
||||
assertThat(lbf.isAutowireCandidate(MARK, qualifiedDescriptor)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void autowireBeanByTypeWithQualifierPrecedence() throws Exception {
|
||||
lbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||
lbf.registerBeanDefinition("testBean", bd);
|
||||
lbf.registerBeanDefinition("spouse", bd2);
|
||||
lbf.registerAlias("test", "testBean");
|
||||
|
||||
assertThat(lbf.resolveDependency(new DependencyDescriptor(getClass().getDeclaredField("testBean"), true), null))
|
||||
.isSameAs(lbf.getBean("spouse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autowireBeanByTypeWithQualifierPrecedenceInAncestor() throws Exception {
|
||||
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
|
||||
parent.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
|
||||
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
|
||||
parent.registerBeanDefinition("test", bd);
|
||||
parent.registerBeanDefinition("spouse", bd2);
|
||||
parent.registerAlias("test", "testBean");
|
||||
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(parent);
|
||||
lbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
|
||||
|
||||
assertThat(lbf.resolveDependency(new DependencyDescriptor(getClass().getDeclaredField("testBean"), true), null))
|
||||
.isSameAs(lbf.getBean("spouse"));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class QualifiedTestBean {
|
||||
|
@ -247,4 +291,8 @@ class QualifierAnnotationAutowireBeanFactoryTests {
|
|||
private @interface TestQualifier {
|
||||
}
|
||||
|
||||
|
||||
@Qualifier("spouse")
|
||||
private TestBean testBean;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue