diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java index fa98718d2706..696655ad0d7f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -116,11 +116,13 @@ public void setEnvironment(ConfigurableEnvironment environment) { /** * Provide a custom {@link BeanNameGenerator} for use with {@link AnnotatedBeanDefinitionReader} * and/or {@link ClassPathBeanDefinitionScanner}, if any. - *

Default is {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}. + *

Default is {@link AnnotationBeanNameGenerator}. *

Any call to this method must occur prior to calls to {@link #register(Class...)} * and/or {@link #scan(String...)}. * @see AnnotatedBeanDefinitionReader#setBeanNameGenerator * @see ClassPathBeanDefinitionScanner#setBeanNameGenerator + * @see AnnotationBeanNameGenerator + * @see FullyQualifiedAnnotationBeanNameGenerator */ public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { this.reader.setBeanNameGenerator(beanNameGenerator); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java index 7bd970b63fc8..ffa1f1a06451 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScan.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2020 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. @@ -94,6 +94,8 @@ * {@link AnnotationBeanNameGenerator} or any custom instance supplied to the * application context at bootstrap time. * @see AnnotationConfigApplicationContext#setBeanNameGenerator(BeanNameGenerator) + * @see AnnotationBeanNameGenerator + * @see FullyQualifiedAnnotationBeanNameGenerator */ Class nameGenerator() default BeanNameGenerator.class; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/FullyQualifiedAnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/FullyQualifiedAnnotationBeanNameGenerator.java index da68da276cb6..5495535d6a77 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/FullyQualifiedAnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/FullyQualifiedAnnotationBeanNameGenerator.java @@ -25,6 +25,11 @@ * a supported type-level annotation such as {@code @Component} (see * {@link AnnotationBeanNameGenerator} for details on supported annotations). * + *

Favor this bean naming strategy over {@code AnnotationBeanNameGenerator} if + * you run into naming conflicts due to multiple autodetected components having the + * same non-qualified class name (i.e., classes with identical names but residing in + * different packages). + * *

Note that an instance of this class is used by default for configuration-level * import purposes; whereas, the default for component scanning purposes is a plain * {@code AnnotationBeanNameGenerator}. diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index d434ac95de15..bbecd6c728a1 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -6941,12 +6941,19 @@ classes were detected, the names would be `myMovieLister` and `movieFinderImpl`: } ---- -NOTE: If you do not want to rely on the default bean-naming strategy, you can provide a -custom bean-naming strategy. First, implement the +If you do not want to rely on the default bean-naming strategy, you can provide a custom +bean-naming strategy. First, implement the {api-spring-framework}/beans/factory/support/BeanNameGenerator.html[`BeanNameGenerator`] interface, and be sure to include a default no-arg constructor. Then, provide the fully qualified class name when configuring the scanner, as the following example annotation -and bean definition show: +and bean definition show. + +TIP: If you run into naming conflicts due to multiple autodetected components having the +same non-qualified class name (i.e., classes with identical names but residing in +different packages), you may need to configure a `BeanNameGenerator` that defaults to the +fully qualified class name for the generated bean name. As of Spring Framework 5.2.3, the +`FullyQualifiedAnnotationBeanNameGenerator` located in package +`org.springframework.context.annotation` can be used for such purposes. [source,java,indent=0,subs="verbatim,quotes",role="primary"] .Java