Introduce BeanNameGenerator based on fully qualified class name
Prior to this commit, Spring offered two top-level implementations of the BeanNameGenerator strategy: DefaultBeanNameGenerator and AnnotationBeanNameGenerator. The latter is used as the default bean name generator for beans picked up via component scanning. In a typical application, this strategy works well; however, if multiple component scanned beans have the same simple class name (i.e., identical names ignoring the package), a BeanDefinitionStoreException is thrown. To address such naming conflicts, users of Spring have had to implement a custom BeanNameGenerator based on the fully qualified class name of such components. Similar conflicts can arise with components registered via configuration class imports (i.e., via @Import), and ConfigurationClassPostProcessor addresses this via an anonymous inner class that extends AnnotationBeanNameGenerator but falls back to using the fully qualified class name if an explicit bean name is not provided via an annotation. This commit extracts the implementation of ConfigurationClassPostProcessor's internal BeanNameGenerator into a new top-level FullyQualifiedAnnotationBeanNameGenerator class that can be used to disambiguate between same-named components residing in different packages that are picked up via component scanning. This bean name generator can be configured via @ComponentScan's nameGenerator attribute. Closes gh-24114
This commit is contained in:
parent
e1fb4a1966
commit
b4c91e7dac
|
@ -57,6 +57,7 @@ import org.springframework.util.StringUtils;
|
|||
* @see org.springframework.stereotype.Service#value()
|
||||
* @see org.springframework.stereotype.Controller#value()
|
||||
* @see javax.inject.Named#value()
|
||||
* @see FullyQualifiedAnnotationBeanNameGenerator
|
||||
*/
|
||||
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -95,14 +95,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
|||
* @since 5.2
|
||||
* @see #setBeanNameGenerator
|
||||
*/
|
||||
public static final AnnotationBeanNameGenerator IMPORT_BEAN_NAME_GENERATOR = new AnnotationBeanNameGenerator() {
|
||||
@Override
|
||||
protected String buildDefaultBeanName(BeanDefinition definition) {
|
||||
String beanClassName = definition.getBeanClassName();
|
||||
Assert.state(beanClassName != null, "No bean class name set");
|
||||
return beanClassName;
|
||||
}
|
||||
};
|
||||
public static final AnnotationBeanNameGenerator IMPORT_BEAN_NAME_GENERATOR =
|
||||
new FullyQualifiedAnnotationBeanNameGenerator();
|
||||
|
||||
private static final String IMPORT_REGISTRY_BEAN_NAME =
|
||||
ConfigurationClassPostProcessor.class.getName() + ".importRegistry";
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An extension of {@code 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 {@code @Component} (see
|
||||
* {@link AnnotationBeanNameGenerator} for details on supported annotations).
|
||||
*
|
||||
* <p>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}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 5.2.3
|
||||
* @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
|
||||
* @see AnnotationBeanNameGenerator
|
||||
* @see ConfigurationClassPostProcessor#IMPORT_BEAN_NAME_GENERATOR
|
||||
*/
|
||||
public class FullyQualifiedAnnotationBeanNameGenerator extends AnnotationBeanNameGenerator {
|
||||
|
||||
@Override
|
||||
protected String buildDefaultBeanName(BeanDefinition definition) {
|
||||
String beanClassName = definition.getBeanClassName();
|
||||
Assert.state(beanClassName != null, "No bean class name set");
|
||||
return beanClassName;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue