From 22d2810ed0583935ed294c5fd598fca1c1916228 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 26 Nov 2025 23:01:55 +0100 Subject: [PATCH] Narrow method annotation check in hasQualifier to setter methods Closes gh-35908 (cherry picked from commit 6c3132cb8cd67c5e9451b48d4dcb440fb28e484c) --- ...erAnnotationAutowireCandidateResolver.java | 9 ++++-- .../AutowiredConfigurationTests.java | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java index d1ae76d6707..f4d97c04635 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/QualifierAnnotationAutowireCandidateResolver.java @@ -376,9 +376,12 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa } MethodParameter methodParam = descriptor.getMethodParameter(); if (methodParam != null) { - for (Annotation annotation : methodParam.getMethodAnnotations()) { - if (isQualifier(annotation.annotationType())) { - return true; + Method method = methodParam.getMethod(); + if (method == null || void.class == method.getReturnType()) { + for (Annotation annotation : methodParam.getMethodAnnotations()) { + if (isQualifier(annotation.annotationType())) { + return true; + } } } } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java index 0f0ca980dff..4c621ccd63b 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java @@ -19,6 +19,7 @@ package org.springframework.context.annotation.configuration; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Collections; import java.util.List; import java.util.Optional; @@ -29,6 +30,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -100,6 +102,16 @@ class AutowiredConfigurationTests { context.close(); } + @Test + void testAutowiredConfigurationMethodDependenciesWithQualifier() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + QualifiedAutowiredMethodConfig.class); + + assertThat(context.getBeansOfType(Colour.class)).isEmpty(); + assertThat(context.getBean(TestBean.class).getName()).isEmpty(); + context.close(); + } + @Test void testAutowiredSingleConstructorSupported() { DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); @@ -297,6 +309,25 @@ class AutowiredConfigurationTests { } + @Configuration + static class QualifiedAutowiredMethodConfig { + + @Bean + @Qualifier("testBean") + public TestBean testBean(Optional colour, Optional> colours) { + if (!colour.isEmpty() || !colours.isEmpty()) { + throw new IllegalStateException("Unexpected match: " + colour + " " + colours); + } + return new TestBean(""); + } + + @Bean + public List someList() { + return Collections.singletonList(new TestBean("shouldNotMatch")); + } + } + + @Configuration static class AutowiredConstructorConfig {