bean的一生----Spring容器启动

2023-10-26

1.我这里通过AnnotationConfigApplicationContext来new一个容器对象;
进入AnnotationConfigApplicationContext看看是怎么创建容器的
可以看到构造方法实现了三个方法:

this();
this.register(componentClasses);
this.refresh();

第一个:this();调用默认构造方法会调用父类的默认构造方法
可以看到他的父类是GenericApplicationContext
这是GenericApplicationContext的默认构造器

这里父类构造器通过DefaultListableBeanFactory来创建一个beanFactory对象

进去DefaultListableBeanFactory看看里面有什么
DefaultListableBeanFactory默认构造器啥也没干,那就看看创建出来的beanFactory有那些信息
一个beanFactory对象所包含的信息,可以看到里面有很多集合
其中有两个集合我认为比较重要一个就是BeanDefinitionMap(bdMap):
用来存放一些beanDefinition(beanDefinition可以理解为一个bean的抽象,里面存放着bean的各种信息,那么为什么要用beanDefinition来抽象一个bean,类对象不可以抽象bean吗?我的理解:不可以的,因为我们将一个类加上注解或者xml告诉Spring这是一个bean,这里bean里面有很多bean特有的属性比如是否懒加载,是否支持循环依赖,是否单例等,而一个普通的类对象无法抽象这些信息,所以我们用BeanDefinition来抽象一个 spring bean,所以Spring用BeanDefinitionMap就是存放BeanDefinition,key是bean的名字,value是BeanDefinition)

另一个就是beanDefinitionNames:用来存放beanName的一个list集合;

第二个方法:register方法
一直进去
可以看到这里调用的是doRegisterBean方法
调用doRegisterBean方法
在这里插入图片描述

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

第一行代码通过AnnotatedGenericBeanDefinition传入beanClass得到对应的beanDefinition对象
在这里插入图片描述
进入registerBeanDefinition— 一直进入最后到DefaultListableBeanFactory的registerBeanDefinition方法

//Spring 源码删减版  在这个方法中最后会将beanDefinition对象放入DeanDefinitionMap中
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
//首先对beanName和beanDefinition进行一个判断
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var8) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
            }
        }
//判断当前的BeanDefinition是在存在BeanDefinitionMap中,一般不存在
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }

            if (existingDefinition.getRole() < beanDefinition.getRole()) {
               ······

            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
        //如果BeanDefinitionMap中不存在当前的BeanDefinition,则进行一系列判断
        //判断当前BD对象是否是正在创建中
            if (this.hasBeanCreationStarted()) {
                synchronized(this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    this.removeManualSingletonName(beanName);
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.removeManualSingletonName(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if (existingDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }
    }

到这里register方法执行完了

第三个方法:refresh方法

未完待续``````

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bean的一生----Spring容器启动 的相关文章

随机推荐