Skip to content

Commit

Permalink
Consider defaultCandidate flag in case of no annotations as well
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoeller committed Feb 20, 2024
1 parent bc01e31 commit 63ca8d5
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,41 +164,40 @@ public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDesc
* 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;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Optional;

import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -85,20 +86,26 @@ void scopedProxy() {
@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();
}

Expand Down Expand Up @@ -233,7 +240,7 @@ public static TestBean testBean1() {

@Bean @Qualifier("interesting")
public static TestBean testBean1x() {
return new TestBean("interesting");
return new TestBean("");
}

@Bean @Boring @Primary
Expand All @@ -245,7 +252,7 @@ public TestBean testBean2(TestBean testBean1) {

@Bean @Boring
public TestBean testBean2x() {
return new TestBean("boring");
return new TestBean("");
}
}

Expand All @@ -259,7 +266,7 @@ public static TestBean testBean1() {

@Bean @Qualifier("interesting") @Fallback
public static TestBean testBean1x() {
return new TestBean("interesting");
return new TestBean("");
}

@Bean @Boring
Expand All @@ -271,7 +278,7 @@ public TestBean testBean2(TestBean testBean1) {

@Bean @Boring @Fallback
public TestBean testBean2x() {
return new TestBean("boring");
return new TestBean("");
}
}

Expand All @@ -283,6 +290,19 @@ static class StandardPojo {
@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 {
Expand Down Expand Up @@ -323,11 +343,15 @@ public TestBean testBean2(@Lazy TestBean testBean1) {
@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")
Expand Down

0 comments on commit 63ca8d5

Please sign in to comment.