Browse Source

Consider defaultCandidate flag in case of no annotations as well

See gh-26528
pull/32318/head
Juergen Hoeller 2 years ago
parent
commit
63ca8d5d17
  1. 61
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java
  2. 38
      spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanMethodQualificationTests.java

61
spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java

@ -164,41 +164,40 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa @@ -164,41 +164,40 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
* Match the given qualifier annotations against the candidate bean definition.
*/
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
if (ObjectUtils.isEmpty(annotationsToSearch)) {
return true;
}
boolean qualifierFound = false;
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
for (Annotation annotation : annotationsToSearch) {
Class<? extends Annotation> type = annotation.annotationType();
boolean checkMeta = true;
boolean fallbackToMeta = false;
if (isQualifier(type)) {
qualifierFound = true;
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
fallbackToMeta = true;
}
else {
checkMeta = false;
if (!ObjectUtils.isEmpty(annotationsToSearch)) {
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
for (Annotation annotation : annotationsToSearch) {
Class<? extends Annotation> type = annotation.annotationType();
boolean checkMeta = true;
boolean fallbackToMeta = false;
if (isQualifier(type)) {
qualifierFound = true;
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
fallbackToMeta = true;
}
else {
checkMeta = false;
}
}
}
if (checkMeta) {
boolean foundMeta = false;
for (Annotation metaAnn : type.getAnnotations()) {
Class<? extends Annotation> metaType = metaAnn.annotationType();
if (isQualifier(metaType)) {
qualifierFound = true;
foundMeta = true;
// Only accept fallback match if @Qualifier annotation has a value...
// Otherwise, it is just a marker for a custom qualifier annotation.
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
return false;
if (checkMeta) {
boolean foundMeta = false;
for (Annotation metaAnn : type.getAnnotations()) {
Class<? extends Annotation> metaType = metaAnn.annotationType();
if (isQualifier(metaType)) {
qualifierFound = true;
foundMeta = true;
// Only accept fallback match if @Qualifier annotation has a value...
// Otherwise, it is just a marker for a custom qualifier annotation.
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
return false;
}
}
}
}
if (fallbackToMeta && !foundMeta) {
return false;
if (fallbackToMeta && !foundMeta) {
return false;
}
}
}
}

38
spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanMethodQualificationTests.java

@ -18,6 +18,7 @@ package org.springframework.context.annotation.configuration; @@ -18,6 +18,7 @@ package org.springframework.context.annotation.configuration;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Optional;
import org.junit.jupiter.api.Test;
@ -85,20 +86,26 @@ class BeanMethodQualificationTests { @@ -85,20 +86,26 @@ class BeanMethodQualificationTests {
@Test
void primary() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(PrimaryConfig.class, StandardPojo.class);
new AnnotationConfigApplicationContext(PrimaryConfig.class, StandardPojo.class, ConstructorPojo.class);
StandardPojo pojo = ctx.getBean(StandardPojo.class);
assertThat(pojo.testBean.getName()).isEqualTo("interesting");
assertThat(pojo.testBean2.getName()).isEqualTo("boring");
ConstructorPojo pojo2 = ctx.getBean(ConstructorPojo.class);
assertThat(pojo2.testBean.getName()).isEqualTo("interesting");
assertThat(pojo2.testBean2.getName()).isEqualTo("boring");
ctx.close();
}
@Test
void fallback() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(FallbackConfig.class, StandardPojo.class);
new AnnotationConfigApplicationContext(FallbackConfig.class, StandardPojo.class, ConstructorPojo.class);
StandardPojo pojo = ctx.getBean(StandardPojo.class);
assertThat(pojo.testBean.getName()).isEqualTo("interesting");
assertThat(pojo.testBean2.getName()).isEqualTo("boring");
ConstructorPojo pojo2 = ctx.getBean(ConstructorPojo.class);
assertThat(pojo2.testBean.getName()).isEqualTo("interesting");
assertThat(pojo2.testBean2.getName()).isEqualTo("boring");
ctx.close();
}
@ -233,7 +240,7 @@ class BeanMethodQualificationTests { @@ -233,7 +240,7 @@ class BeanMethodQualificationTests {
@Bean @Qualifier("interesting")
public static TestBean testBean1x() {
return new TestBean("interesting");
return new TestBean("");
}
@Bean @Boring @Primary
@ -245,7 +252,7 @@ class BeanMethodQualificationTests { @@ -245,7 +252,7 @@ class BeanMethodQualificationTests {
@Bean @Boring
public TestBean testBean2x() {
return new TestBean("boring");
return new TestBean("");
}
}
@ -259,7 +266,7 @@ class BeanMethodQualificationTests { @@ -259,7 +266,7 @@ class BeanMethodQualificationTests {
@Bean @Qualifier("interesting") @Fallback
public static TestBean testBean1x() {
return new TestBean("interesting");
return new TestBean("");
}
@Bean @Boring
@ -271,7 +278,7 @@ class BeanMethodQualificationTests { @@ -271,7 +278,7 @@ class BeanMethodQualificationTests {
@Bean @Boring @Fallback
public TestBean testBean2x() {
return new TestBean("boring");
return new TestBean("");
}
}
@ -283,6 +290,19 @@ class BeanMethodQualificationTests { @@ -283,6 +290,19 @@ class BeanMethodQualificationTests {
@Autowired @Boring TestBean testBean2;
}
@Component @Lazy
static class ConstructorPojo {
TestBean testBean;
TestBean testBean2;
ConstructorPojo(@Qualifier("interesting") TestBean testBean, @Boring TestBean testBean2) {
this.testBean = testBean;
this.testBean2 = testBean2;
}
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Boring {
@ -323,11 +343,15 @@ class BeanMethodQualificationTests { @@ -323,11 +343,15 @@ class BeanMethodQualificationTests {
@InterestingPojo
static class CustomPojo {
@Autowired(required=false) TestBean plainBean;
TestBean plainBean;
@InterestingNeed TestBean testBean;
@InterestingNeedWithRequiredOverride(required=false) NestedTestBean nestedTestBean;
public CustomPojo(Optional<TestBean> plainBean) {
this.plainBean = plainBean.orElse(null);
}
}
@Bean(defaultCandidate=false) @Lazy @Qualifier("interesting")

Loading…
Cancel
Save