Skip to content

Commit 63ca8d5

Browse files
committed
Consider defaultCandidate flag in case of no annotations as well
See gh-26528
1 parent bc01e31 commit 63ca8d5

File tree

2 files changed

+61
-38
lines changed

2 files changed

+61
-38
lines changed

Diff for: spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java

+30-31
Original file line numberDiff line numberDiff line change
@@ -164,41 +164,40 @@ public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDesc
164164
* Match the given qualifier annotations against the candidate bean definition.
165165
*/
166166
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
167-
if (ObjectUtils.isEmpty(annotationsToSearch)) {
168-
return true;
169-
}
170167
boolean qualifierFound = false;
171-
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
172-
for (Annotation annotation : annotationsToSearch) {
173-
Class<? extends Annotation> type = annotation.annotationType();
174-
boolean checkMeta = true;
175-
boolean fallbackToMeta = false;
176-
if (isQualifier(type)) {
177-
qualifierFound = true;
178-
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
179-
fallbackToMeta = true;
180-
}
181-
else {
182-
checkMeta = false;
168+
if (!ObjectUtils.isEmpty(annotationsToSearch)) {
169+
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
170+
for (Annotation annotation : annotationsToSearch) {
171+
Class<? extends Annotation> type = annotation.annotationType();
172+
boolean checkMeta = true;
173+
boolean fallbackToMeta = false;
174+
if (isQualifier(type)) {
175+
qualifierFound = true;
176+
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
177+
fallbackToMeta = true;
178+
}
179+
else {
180+
checkMeta = false;
181+
}
183182
}
184-
}
185-
if (checkMeta) {
186-
boolean foundMeta = false;
187-
for (Annotation metaAnn : type.getAnnotations()) {
188-
Class<? extends Annotation> metaType = metaAnn.annotationType();
189-
if (isQualifier(metaType)) {
190-
qualifierFound = true;
191-
foundMeta = true;
192-
// Only accept fallback match if @Qualifier annotation has a value...
193-
// Otherwise, it is just a marker for a custom qualifier annotation.
194-
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
195-
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
196-
return false;
183+
if (checkMeta) {
184+
boolean foundMeta = false;
185+
for (Annotation metaAnn : type.getAnnotations()) {
186+
Class<? extends Annotation> metaType = metaAnn.annotationType();
187+
if (isQualifier(metaType)) {
188+
qualifierFound = true;
189+
foundMeta = true;
190+
// Only accept fallback match if @Qualifier annotation has a value...
191+
// Otherwise, it is just a marker for a custom qualifier annotation.
192+
if ((fallbackToMeta && ObjectUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
193+
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
194+
return false;
195+
}
197196
}
198197
}
199-
}
200-
if (fallbackToMeta && !foundMeta) {
201-
return false;
198+
if (fallbackToMeta && !foundMeta) {
199+
return false;
200+
}
202201
}
203202
}
204203
}

Diff for: spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanMethodQualificationTests.java

+31-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.lang.annotation.Retention;
2020
import java.lang.annotation.RetentionPolicy;
21+
import java.util.Optional;
2122

2223
import org.junit.jupiter.api.Test;
2324

@@ -85,20 +86,26 @@ void scopedProxy() {
8586
@Test
8687
void primary() {
8788
AnnotationConfigApplicationContext ctx =
88-
new AnnotationConfigApplicationContext(PrimaryConfig.class, StandardPojo.class);
89+
new AnnotationConfigApplicationContext(PrimaryConfig.class, StandardPojo.class, ConstructorPojo.class);
8990
StandardPojo pojo = ctx.getBean(StandardPojo.class);
9091
assertThat(pojo.testBean.getName()).isEqualTo("interesting");
9192
assertThat(pojo.testBean2.getName()).isEqualTo("boring");
93+
ConstructorPojo pojo2 = ctx.getBean(ConstructorPojo.class);
94+
assertThat(pojo2.testBean.getName()).isEqualTo("interesting");
95+
assertThat(pojo2.testBean2.getName()).isEqualTo("boring");
9296
ctx.close();
9397
}
9498

9599
@Test
96100
void fallback() {
97101
AnnotationConfigApplicationContext ctx =
98-
new AnnotationConfigApplicationContext(FallbackConfig.class, StandardPojo.class);
102+
new AnnotationConfigApplicationContext(FallbackConfig.class, StandardPojo.class, ConstructorPojo.class);
99103
StandardPojo pojo = ctx.getBean(StandardPojo.class);
100104
assertThat(pojo.testBean.getName()).isEqualTo("interesting");
101105
assertThat(pojo.testBean2.getName()).isEqualTo("boring");
106+
ConstructorPojo pojo2 = ctx.getBean(ConstructorPojo.class);
107+
assertThat(pojo2.testBean.getName()).isEqualTo("interesting");
108+
assertThat(pojo2.testBean2.getName()).isEqualTo("boring");
102109
ctx.close();
103110
}
104111

@@ -233,7 +240,7 @@ public static TestBean testBean1() {
233240

234241
@Bean @Qualifier("interesting")
235242
public static TestBean testBean1x() {
236-
return new TestBean("interesting");
243+
return new TestBean("");
237244
}
238245

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

246253
@Bean @Boring
247254
public TestBean testBean2x() {
248-
return new TestBean("boring");
255+
return new TestBean("");
249256
}
250257
}
251258

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

260267
@Bean @Qualifier("interesting") @Fallback
261268
public static TestBean testBean1x() {
262-
return new TestBean("interesting");
269+
return new TestBean("");
263270
}
264271

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

272279
@Bean @Boring @Fallback
273280
public TestBean testBean2x() {
274-
return new TestBean("boring");
281+
return new TestBean("");
275282
}
276283
}
277284

@@ -283,6 +290,19 @@ static class StandardPojo {
283290
@Autowired @Boring TestBean testBean2;
284291
}
285292

293+
@Component @Lazy
294+
static class ConstructorPojo {
295+
296+
TestBean testBean;
297+
298+
TestBean testBean2;
299+
300+
ConstructorPojo(@Qualifier("interesting") TestBean testBean, @Boring TestBean testBean2) {
301+
this.testBean = testBean;
302+
this.testBean2 = testBean2;
303+
}
304+
}
305+
286306
@Qualifier
287307
@Retention(RetentionPolicy.RUNTIME)
288308
public @interface Boring {
@@ -323,11 +343,15 @@ public TestBean testBean2(@Lazy TestBean testBean1) {
323343
@InterestingPojo
324344
static class CustomPojo {
325345

326-
@Autowired(required=false) TestBean plainBean;
346+
TestBean plainBean;
327347

328348
@InterestingNeed TestBean testBean;
329349

330350
@InterestingNeedWithRequiredOverride(required=false) NestedTestBean nestedTestBean;
351+
352+
public CustomPojo(Optional<TestBean> plainBean) {
353+
this.plainBean = plainBean.orElse(null);
354+
}
331355
}
332356

333357
@Bean(defaultCandidate=false) @Lazy @Qualifier("interesting")

0 commit comments

Comments
 (0)