From d3d414c3c72437795f9bf5f2705ddbcc0959d879 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 7 Aug 2023 15:00:08 +0200 Subject: [PATCH] Reject @Bean method with void return type Closes gh-31007 --- .../context/annotation/BeanMethod.java | 16 +++++++++++++++- .../ConfigurationClassProcessingTests.java | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 2 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 5f01df18b1a..ea09841aee3 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 @@ -42,8 +42,13 @@ final class BeanMethod extends ConfigurationMethod { @Override public void validate(ProblemReporter problemReporter) { + if ("void".equals(getMetadata().getReturnTypeName())) { + // declared as void: potential misuse of @Bean, maybe meant as init method instead? + problemReporter.error(new VoidDeclaredMethodError()); + } + if (getMetadata().isStatic()) { - // static @Bean methods have no constraints to validate -> return immediately + // static @Bean methods have no further constraints to validate -> return immediately return; } @@ -71,6 +76,15 @@ final class BeanMethod extends ConfigurationMethod { } + private class VoidDeclaredMethodError extends Problem { + + VoidDeclaredMethodError() { + super("@Bean method '%s' must not be declared as void; change the method's return type or its annotation." + .formatted(getMetadata().getMethodName()), getResourceLocation()); + } + } + + private class NonOverridableMethodError extends Problem { NonOverridableMethodError() { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java index 9c715f1d25f..22273a9e7b7 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationClassProcessingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,6 +143,12 @@ class ConfigurationClassProcessingTests { initBeanFactory(ConfigWithFinalBean.class)); } + @Test // gh-31007 + void voidBeanMethod() { + assertThatExceptionOfType(BeanDefinitionParsingException.class).isThrownBy(() -> + initBeanFactory(ConfigWithVoidBean.class)); + } + @Test void simplestPossibleConfig() { BeanFactory factory = initBeanFactory(SimplestPossibleConfig.class); @@ -432,6 +438,14 @@ class ConfigurationClassProcessingTests { } + @Configuration + static class ConfigWithVoidBean { + + public @Bean void testBean() { + } + } + + @Configuration static class SimplestPossibleConfig {