spring · 2025-01-14 0

Spring beanDefinitionNames、manualSingletonNames、registerBeanDefinition、registerSingleton、getBean

  1. beanDefinitionNames 这个属性通常指的是包含所有已注册到 Spring 应用上下文中的 Bean 定义名称的集合。
  2. manualSingletonNames 这个属性是指那些被显式地作为单例(singleton)注册到 Spring 容器中的 Bean 的名字集合。

示例

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.22</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.22</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.22</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>5.3.22</version>
    </dependency>
</dependencies>
public class Service1 {
}
public class AppConfig {

    @Bean
    public Service1 service1() {
        return new Service1();
    }
}
public class MyMain {

    public static void main(String[] args) {
        // 自动注册:
        // 1.执行 registerBeanDefinition 时
        // 1.1 beanDefinitionMap 加入 beanName 和 beanDefinition
        // 1.2 beanDefinitionNames 加入 beanName
        // 1.3 manualSingletonNames 移除 beanName
        // 2.执行 getBean 时,
        // 2.1 alreadyCreated 加入 beanName
        // 3.执行 getSingleton 和 addSingleton 时
        // 3.1 singletonObjects 加入 beanName 和 bean
        // 3.2 singletonFactories 移除 beanName
        // 3.3 earlySingletonObjects 移除 beanName
        // 3.4 registeredSingletons 加入 beanName
        // 总结:
        // 1.alreadyCreated 加入 beanName
        // 2.beanDefinitionMap 加入 beanName 和 beanDefinition
        // 3.beanDefinitionNames 加入 beanName
        // 4.singletonObjects 加入 beanName 和 bean
        // 5.registeredSingletons 加入 beanName
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();

        // 手动注册
        // 1.执行 registerBeanDefinition 时
        // 1.1 beanDefinitionMap 加入 beanName 和 beanDefinition
        // 1.2 beanDefinitionNames 加入 beanName
        // 1.3 manualSingletonNames 移除 beanName
        BeanDefinitionBuilder service22Builder = BeanDefinitionBuilder.genericBeanDefinition(Service1.class);
        beanFactory.registerBeanDefinition("service11", service22Builder.getBeanDefinition());
        // 2.执行 getBean 时
        // 2.1 alreadyCreated 加入 beanName
        // 3.执行 getSingleton 和 addSingleton 时
        // 3.1 singletonObjects 加入 beanName 和 bean
        // 3.2 singletonFactories 移除 beanName
        // 3.3 earlySingletonObjects 移除 beanName
        // 3.4 registeredSingletons 加入 beanName
        // 总结:
        // 1.alreadyCreated 加入 beanName
        // 2.beanDefinitionMap 加入 beanName 和 beanDefinition
        // 3.beanDefinitionNames 加入 beanName
        // 4.singletonObjects 加入 beanName 和 bean
        // 5.registeredSingletons 加入 beanName
        Object bean = beanFactory.getBean("service11");

        // 手动注册:
        // 1.判断 singletonObjects,是否包含 beanName,若包含,则报错。若不包含,则继续执行
        // 2.执行 addSingleton 时
        // 2.1 singletonObjects 加入 beanName 和 bean
        // 2.2 singletonFactories 移除 beanName
        // 2.3 earlySingletonObjects 移除 beanName
        // 2.4 registeredSingletons 加入 beanName
        // 3.判断 beanDefinitionMap 是否有此 beanName,若没有,则继续执行
        // 3.1manualSingletonNames 加入 beanName
        // 总结:
        // 1.singletonObjects 加入 beanName 和 bean
        // 2.registeredSingletons 加入 beanName
        // 3.manualSingletonNames 加入 beanName
        beanFactory.registerSingleton("service12", new Service1());

        // 执行 addSingleton

        // 1.根据 beanName,从 singletonObjects 获得 bean
        Object result1 = beanFactory.getBean("service12");
        // 1.根据 beanName,从 singletonObjects 获得 bean
        // 2.判断得到的 bean,和传递的 class,是否符合,若不符合,则报错
        Service1 result2 = beanFactory.getBean("service12", Service1.class);
        // 1.1 循环 beanDefinitionNames,从 singletonObjects,根据 beanName 获得 bean,判断 bean 与传递的是否符合,若符合返回 beanName
        // 1.2 循环 manualSingletonNames,从 singletonObjects,根据 beanName 获得 bean,判断 bean 与传递的是否符合,若符合返回 beanName
        // 2.根据 beanName,从 singletonObjects,获得 bean,若获得多个bean,且没有 primary bean,则抛出异常
        Service1 result3 = beanFactory.getBean(Service1.class);
    }
}