From 5c68f3f4ef8a3d7b93443b68f04778dedfb03eed Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 17 Jun 2024 21:08:21 +0200 Subject: [PATCH] Reject @Bean method with method-level @Autowired declaration Closes gh-33051 --- .../context/annotation/BeanMethod.java | 16 ++++++++++++++++ .../AutowiredConfigurationTests.java | 8 ++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java b/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java index 1b41d938c289..cd4d18724422 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java @@ -18,6 +18,7 @@ import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.parsing.Problem; import org.springframework.beans.factory.parsing.ProblemReporter; import org.springframework.core.type.MethodMetadata; @@ -45,6 +46,12 @@ final class BeanMethod extends ConfigurationMethod { @Override @SuppressWarnings("NullAway") public void validate(ProblemReporter problemReporter) { + if (getMetadata().getAnnotationAttributes(Autowired.class.getName()) != null) { + // declared as @Autowired: semantic mismatch since @Bean method arguments are autowired + // in any case whereas @Autowired methods are setter-like methods on the containing class + problemReporter.error(new AutowiredDeclaredMethodError()); + } + if ("void".equals(getMetadata().getReturnTypeName())) { // declared as void: potential misuse of @Bean, maybe meant as init method instead? problemReporter.error(new VoidDeclaredMethodError()); @@ -89,6 +96,15 @@ private static String getLocalMethodIdentifier(MethodMetadata metadata) { } + private class AutowiredDeclaredMethodError extends Problem { + + AutowiredDeclaredMethodError() { + super("@Bean method '%s' must not be declared as autowired; remove the method-level @Autowired annotation." + .formatted(getMetadata().getMethodName()), getResourceLocation()); + } + } + + private class VoidDeclaredMethodError extends Problem { VoidDeclaredMethodError() { 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 0d78cc33b8c1..58ef1e25ffc8 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 @@ -30,6 +30,7 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; @@ -47,6 +48,7 @@ import org.springframework.util.Assert; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** * System tests covering use of {@link Autowired} and {@link Value} within @@ -187,10 +189,8 @@ void testValueInjectionWithProviderMethodArguments() { @Test void testValueInjectionWithAccidentalAutowiredAnnotations() { - AnnotationConfigApplicationContext context = - new AnnotationConfigApplicationContext(ValueConfigWithAccidentalAutowiredAnnotations.class); - doTestValueInjection(context); - context.close(); + assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(() -> + new AnnotationConfigApplicationContext(ValueConfigWithAccidentalAutowiredAnnotations.class)); } private void doTestValueInjection(BeanFactory context) {