Affects: Version 5
@ComponentScan will register Beans with a name generated from the class of the component.
Problem:
Having two classes with the same name UserMapper in different packages will result in an BeanDefinitionStoreException
1. org.company.dom -> userMapper
2. org.company.web -> userMapper
Suggestion:
Include the package in the bean name:
1. org.company.dom.userMapper
2. org.company.web.userMapper
Why:
I'm forced to duplicate package information in the class name:
1. org.company.dom; class domUserMapper
2. org.company.web; class webUserMapper
same giving each Component a package prefixed name:
1. org.company.dom; @Component("domUserMapper") class userMapper
2. org.company.web; @Component("webUserMapper") class userMapper
Especially with generated sources like MapStruct this is not possible.
Or should I write a custom BeanNamingStrategy. For this I do not find so much information, so I guess it's not that famous...
Comment From: sbrannen
Implementing a custom BeanNameGenerator is a perfectly viable solution to this kind of problem. I've seen that done in real-world applications.
You can register a custom implementation via @ComponentScan(nameGenerator =...).
Does that meet your needs?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: torsten-github
Yes, a custom BeanNameGenerator works perfectly. Thank you.
Maybe this would be a good enhancement for the spring-boot project. They could supply a property to choose a custom BeanNameGenerator... So I would save me the boilerplate code (10 Lines) in my main class.
For completness and to help others: This is my current solution: ```java @SpringBootApplication @ComponentScan(nameGenerator = CustomGenerator.class) public class App extends SpringBootServletInitializer {
public static void main(String[] args) { SpringApplication.run(App.class, args); }
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application .sources(App.class); }
public static class CustomGenerator extends AnnotationBeanNameGenerator { @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return definition.getBeanClassName(); } } }
Comment From: sbrannen
Yes, a custom
BeanNameGeneratorworks perfectly. Thank you.
Great! And... you're welcome.
In light of that, I am closing this issue.
I also see that you raised https://github.com/spring-projects/spring-boot/issues/19346 requesting special support in Spring Boot.
Comment From: philwebb
@sbrannen Do you think it's worth surfacing a fully-qualified variant similar ConfigurationClassPostProcessor.IMPORT_BEAN_NAME_GENERATOR that could be generally used?
Comment From: sbrannen
@philwebb, yes, I think that could be generally useful since I've seen custom ones in the wild a few times.
And you're right: no real need to have ConfigurationClassPostProcessor.IMPORT_BEAN_NAME_GENERATOR defined as an anonymous inner class.
Reopening to see if @jhoeller agrees.