spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.67k stars 38.15k forks source link

`BeanNameGenerator` does not apply to `@Bean`-annotated methods #33448

Open kamildoleglo opened 2 months ago

kamildoleglo commented 2 months ago

Affects: 6.1.12 (and AFAIK all previous Spring versions)


What I'm trying to do:

I'm trying to override the default naming behavior for Spring Beans. I want all beans to be named with a fully-qualified name, otherwise the beans may crash upon startup - they may have the same names, since the project I'm working on is quite large and a number of people is working on it simultaneously. Moreover we obfuscate some parts of the code, which may lead to methods having the same name (but different fully-qualified names) at runtime.

I have used the FullyQualifiedAnnotationBeanNameGenerator in the @SpringBoot configuration:

@SpringBootApplication(
 (...)
  nameGenerator = FullyQualifiedAnnotationBeanNameGenerator::class
)

and it works fine for all @Component classes. The issue is that names of beans provided by @Bean-annotated methods, e.g.

package some.package
@Bean
fun foo(): Bar = Bar()

are still derived from the method name, so in this example the bean will be named foo instead of some.package.foo.

The FullyQualifiedAnnotationBeanNameGenerator is then also misleading as it only covers Components (and all annotations that derive from it, like @Repository or @Service); maybe ComponentNameGenerator would be better in that case.

sbrannen commented 2 months ago

Hi @kamildoleglo,

Congratulations on creating your first issue for the Spring Framework. 👍

names of beans provided by @Bean-annotated methods [...] are still derived from the method name, so in this example the bean will be named foo instead of some.package.foo.

That's by design and documented as such.

The FullyQualifiedAnnotationBeanNameGenerator is then also misleading as it only covers Components (and all annotations that derive from it, like @Repository or @Service);

I'm not sure how that is misleading since its Javadoc explicitly states that it is:

An extension of AnnotationBeanNameGenerator that uses the fully qualified class name as the default bean name if an explicit bean name is not supplied via a supported type-level annotation such as @Component (see AnnotationBeanNameGenerator for details on supported annotations).

And that links to the Javadoc for AnnotationBeanNameGenerator which explicitly states that it is a:

BeanNameGenerator implementation for bean classes annotated with the @Component annotation or with another annotation that is itself annotated with @Component as a meta-annotation. For example, Spring's stereotype annotations (such as @Repository) are themselves annotated with @Component.

maybe ComponentNameGenerator would be better in that case.

Perhaps, but it's too late to change the names of those classes. AnnotationBeanNameGenerator has existed since Spring Framework 2.5 (2007).

What made you think that BeanNameGenerator applies to @Bean-annotated methods?

kamildoleglo commented 2 months ago

Thanks for the response! Yeah, I agree that the docs state that, I guess the type-level here being the keyword. IMHO they could also mention explicitly that the FullyQualifiedAnnotationBeanNameGenerator does not work for @Bean-annotated methods though, but the naming nor the documentation is not the main point there. I guess it could be restated as more of a question: Is there any way of overriding bean name generation for all beans and not just some of them? I didn't find the way to do it and I do believe this to be a bug, because from the user perspective I don't really see why @Bean-annotated methods are treated differently than @Component-annotated types

And1sS commented 1 month ago

Thanks for the response! Yeah, I agree that the docs state that, I guess the type-level here being the keyword. IMHO they could also mention explicitly that the FullyQualifiedAnnotationBeanNameGenerator does not work for @Bean-annotated methods though, but the naming nor the documentation is not the main point there. I guess it could be restated as more of a question: Is there any way of overriding bean name generation for all beans and not just some of them? I didn't find the way to do it and I do believe this to be a bug, because from the user perspective I don't really see why @Bean-annotated methods are treated differently than @Component-annotated types

@sbrannen Hi, I am having exactly the same question. Any updates?

Net-burst commented 1 month ago

@sbrannen basically the same question. Why we can have a FQN functionality for @Component, but not for @Bean?

CTMBNara commented 1 month ago

@sbrannen it would be nice to get any updates on this 😅

simpleusr commented 2 days ago

@sbrannen , I have the same problem. It would be great if we could have the same option of using fully qualified method name . If I am not mistaken applying a simple strategy can provide the requested fqn

https://github.com/spring-projects/spring-framework/blob/d92c57f7a5ab1b19f1c6d5a29ab691f2b1e66ee7/spring-context/src/main/java/org/springframework/context/annotation/BeanAnnotationHelper.java#L48