Consistently evaluate defaultCandidate flag on constructors and methods
Closes gh-33762
This commit is contained in:
parent
6f9413ba31
commit
ee1fe8a1e9
|
@ -154,26 +154,35 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
|
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
|
||||||
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
|
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
|
||||||
if (match) {
|
return false;
|
||||||
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
|
}
|
||||||
if (match) {
|
Boolean checked = checkQualifiers(bdHolder, descriptor.getAnnotations());
|
||||||
MethodParameter methodParam = descriptor.getMethodParameter();
|
if (checked != Boolean.FALSE) {
|
||||||
if (methodParam != null) {
|
MethodParameter methodParam = descriptor.getMethodParameter();
|
||||||
Method method = methodParam.getMethod();
|
if (methodParam != null) {
|
||||||
if (method == null || void.class == method.getReturnType()) {
|
Method method = methodParam.getMethod();
|
||||||
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
|
if (method == null || void.class == method.getReturnType()) {
|
||||||
|
Boolean methodChecked = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
|
||||||
|
if (methodChecked != null && checked == null) {
|
||||||
|
checked = methodChecked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return match;
|
return (checked == Boolean.TRUE ||
|
||||||
|
(checked == null && ((RootBeanDefinition) bdHolder.getBeanDefinition()).isDefaultCandidate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match the given qualifier annotations against the candidate bean definition.
|
* Match the given qualifier annotations against the candidate bean definition.
|
||||||
|
* @return {@code false} if a qualifier has been found but not matched,
|
||||||
|
* {@code true} if a qualifier has been found and matched,
|
||||||
|
* {@code null} if no qualifier has been found at all
|
||||||
*/
|
*/
|
||||||
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
|
|
||||||
|
@Nullable
|
||||||
|
protected Boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
|
||||||
boolean qualifierFound = false;
|
boolean qualifierFound = false;
|
||||||
if (!ObjectUtils.isEmpty(annotationsToSearch)) {
|
if (!ObjectUtils.isEmpty(annotationsToSearch)) {
|
||||||
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
|
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
|
||||||
|
@ -217,7 +226,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (qualifierFound || ((RootBeanDefinition) bdHolder.getBeanDefinition()).isDefaultCandidate());
|
return (qualifierFound ? true : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -195,6 +195,28 @@ class BeanMethodQualificationTests {
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void customWithConstructor() {
|
||||||
|
AnnotationConfigApplicationContext ctx = context(CustomConfig.class, CustomPojoWithConstructor.class);
|
||||||
|
|
||||||
|
CustomPojoWithConstructor pojo = ctx.getBean(CustomPojoWithConstructor.class);
|
||||||
|
assertThat(pojo.plainBean).isNull();
|
||||||
|
assertThat(pojo.testBean.getName()).isEqualTo("interesting");
|
||||||
|
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void customWithMethod() {
|
||||||
|
AnnotationConfigApplicationContext ctx = context(CustomConfig.class, CustomPojoWithMethod.class);
|
||||||
|
|
||||||
|
CustomPojoWithMethod pojo = ctx.getBean(CustomPojoWithMethod.class);
|
||||||
|
assertThat(pojo.plainBean).isNull();
|
||||||
|
assertThat(pojo.testBean.getName()).isEqualTo("interesting");
|
||||||
|
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void beanNamesForAnnotation() {
|
void beanNamesForAnnotation() {
|
||||||
AnnotationConfigApplicationContext ctx = context(StandardConfig.class);
|
AnnotationConfigApplicationContext ctx = context(StandardConfig.class);
|
||||||
|
@ -327,6 +349,7 @@ class BeanMethodQualificationTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class EffectivePrimaryConfig {
|
static class EffectivePrimaryConfig {
|
||||||
|
|
||||||
|
@ -346,6 +369,7 @@ class BeanMethodQualificationTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Component @Lazy
|
@Component @Lazy
|
||||||
static class StandardPojo {
|
static class StandardPojo {
|
||||||
|
|
||||||
|
@ -418,6 +442,35 @@ class BeanMethodQualificationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@InterestingPojo
|
||||||
|
static class CustomPojoWithConstructor {
|
||||||
|
|
||||||
|
TestBean plainBean;
|
||||||
|
|
||||||
|
TestBean testBean;
|
||||||
|
|
||||||
|
public CustomPojoWithConstructor(Optional<TestBean> plainBean, @InterestingNeed TestBean testBean) {
|
||||||
|
this.plainBean = plainBean.orElse(null);
|
||||||
|
this.testBean = testBean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@InterestingPojo
|
||||||
|
static class CustomPojoWithMethod {
|
||||||
|
|
||||||
|
TestBean plainBean;
|
||||||
|
|
||||||
|
TestBean testBean;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void applyDependencies(Optional<TestBean> plainBean, @InterestingNeed TestBean testBean) {
|
||||||
|
this.plainBean = plainBean.orElse(null);
|
||||||
|
this.testBean = testBean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Qualifier
|
@Qualifier
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@interface Boring {
|
@interface Boring {
|
||||||
|
|
Loading…
Reference in New Issue