当一个组件作为扫描过程的一部分被自动检测到时,它的 Bean 名称由该扫描器已知的BeanNameGenerator 策略生成。默认情况下,任何包含名称值的 Spring 原型注解(@Component@Repository@Service@Controller)都会向相应的 Bean 定义提供该名称。

    如果这样的注解 不包含名称值,或者对于任何其他检测到的组件(比如那些由自定义过滤器发现的组件),默认的 Bean 类名称生成器会返回未加大写的非限定类名称。例如,如果检测到以下组件类,其名称将是 myMovieLister 和 movieFinderImpl。

    1. @Service("myMovieLister")
    2. public class SimpleMovieLister {
    3. // ...
    4. }
    5. @Repository
    6. public class MovieFinderImpl implements MovieFinder {
    7. // ...
    8. }

    如果你不想依赖默认的 Bean-naming 策略,你可以提供一个自定义的 Bean-naming 策略。首先,实现BeanNameGenerator 接口,并确保包含一个默认的无参数构造函数。然后,在配置扫描器时提供完全合格的类名,正如下面的注解和 Bean 定义的例子所示。

    :::tips 如果你由于多个自动检测的组件具有相同的非限定类名称(即具有相同名称的类,但驻留在不同的包中)而遇到命名冲突,你可能需要配置一个 BeanNameGenerator,默认为生成的 Bean 名称为完全限定的类名称。从 Spring Framework 5.2.3 开始,位于包 org.springframework.context.annotation 中的FullyQualifiedAnnotationBeanNameGenerator 可以用于此类目的。 :::

    1. @Configuration
    2. @ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
    3. public class AppConfig {
    4. // ...
    5. }
    1. <beans>
    2. <context:component-scan base-package="org.example"
    3. name-generator="org.example.MyNameGenerator" />
    4. </beans>

    自定义名称策略如下,将类路径作为名称:

    1. package cn.mrcode.study.springdocsread.web;
    2. import org.springframework.beans.factory.config.BeanDefinition;
    3. import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    4. import org.springframework.beans.factory.support.BeanNameGenerator;
    5. /**
    6. * @author mrcode
    7. */
    8. public class MyBeanNameGenerator implements BeanNameGenerator {
    9. /**
    10. * 为给定的 bean 定义生成一个 bean 名称。
    11. * @param definition bean 定义
    12. * @param registry 该 bean 注册的注册表
    13. * @return
    14. */
    15. @Override
    16. public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    17. // 返回 bean 的路径 cn.mrcode.study.springdocsread.web.Config
    18. final String beanClassName = definition.getBeanClassName();
    19. return beanClassName;
    20. }
    21. }

    默认的策略对于 cn.mrcode.study.springdocsread.web.Config 产生的 Config 对象的 bean 为 Config,而我们上面自定义产生的名称就是他的类路径 cn.mrcode.study.springdocsread.web.Config :::tips 另外上面提到过了 5.2.3 版本开始,Spring 提供了一个全路径名称的策略类 FullyQualifiedAnnotationBeanNameGenerator :::

    作为一般规则,每当其他组件可能对注解进行显式引用时,请考虑使用注解指定名称。另一方面,只要容器负责连接,自动生成的名称就足够了。