14

I want to specify a custom BeanNamingStrategy while configuring my application with Spring Boot. By default, Spring Boot uses the MethodNameStrategy which is a BeanNamingStrategy.

The reason I want to do this is because I have abstract parent classes which my consumers will create configuration subclasses of. The methods in the parent classes have the same names as each other and so are not getting registered for different implementations of the child classes. My custom BeanNamingStrategy will attach the simple name of the configuration class to certain bean names.

Normally in a Spring application you can pass a custom BeanNamingStrategy using the setBeanNamingStrategy method of the ApplicationContext. However if Spring Boot is creating the ApplicationContext, how can I do this?

Adam Burley
  • 5,551
  • 4
  • 51
  • 72

2 Answers2

10

The SpringApplicationBuilder has a method beanNameGenerator() that lets you pass in a custom generator.

See 22.3 Fluent builder API in the Spring Boot reference for how to work with the fluent API.


Unfortunately this doesn't help you, as this only applies to @Component-style class annotations and not to @Bean methods, for which the names are hard coded using this method.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • Thanks, but the `BeanNameGenerator` seems to not be called for `@Bean`-annotated methods (within `@Configuration`-annotated classes), only for `@Component`-annotated classes and for the `@Configuration`-annotated classes themselves. Is there a different object called to generate bean names for methods annotated with `@Bean`? – Adam Burley Oct 12 '15 at 14:26
  • @Kidburla that's strange, because the [`ConfigurationClassPostProcessor`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ConfigurationClassPostProcessor.html) which is responsible for evaluating `@Configuration` classes clearly is aware of `BeanNameGenerator`: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ConfigurationClassPostProcessor.html#setBeanNameGenerator-org.springframework.beans.factory.support.BeanNameGenerator- – Sean Patrick Floyd Oct 12 '15 at 14:49
  • The javadoc you have linked explicitly states "Note that this strategy does *not* apply to `Bean` methods". My understanding was that the `BeanNamingStrategy` was used for `Bean` methods and the `BeanNameGenerator` is only used for resolving beans from annotations at the class-level. – Adam Burley Oct 12 '15 at 14:51
  • Looks like the strategy for determining bean names from `Bean` methods is now hard-coded :-( Not sure if there is any way to override this: http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-context/4.1.6.RELEASE/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java#ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod%28org.springframework.context.annotation.BeanMethod%29 – Adam Burley Oct 12 '15 at 15:05
  • Yeah, just figured as much. Here's the link on Github: https://github.com/spring-projects/spring-framework/blob/f41de12cf62aebf1be9b30be590c12eb2c030853/spring-context/src/main/java/org/springframework/context/annotation/BeanAnnotationHelper.java – Sean Patrick Floyd Oct 12 '15 at 15:07
  • 1
    @Kidburla sounds to me like something you should request as feature – Sean Patrick Floyd Oct 12 '15 at 15:11
3

You can also use @ComponentScan(nameGenerator = ...) annotation on your main Spring Boot application class:

@SpringBootApplication
@ComponentScan(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
BeshEater
  • 143
  • 2
  • 7
  • 1
    **Beware:** you might have issues w/ `@SpringBootTest` and `@WebMvcTest` using this approach. If you do run into problems, see [this question](https://stackoverflow.com/questions/47054716/componentscan-in-application-class-breaks-webmvctest-and-springboottest) for help/more details. – Priidu Neemre Mar 01 '21 at 12:51
  • 3
    Seems like an even better approach is to use `@SpringBootApplication(nameGenerator = ...)` directly, which avoids this issue altogether. See [here](https://github.com/spring-projects/spring-boot/issues/19346) for more details. – Priidu Neemre Mar 01 '21 at 13:23