bean的加载流程(已完结)

针对每一个beanDefinition,初始化bean

SpringBoot启动流程往期博客:

SpringBoot启动流程

应用上下文的刷新工作

ConfigurationClassPostProcessor

一、getBean()

直接调用doGetBean()方法

二、doGetBean()

1、getSingleton(beanName)

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null && allowEarlyReference) {
            synchronized (this.singletonObjects) {
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null) {
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            singletonObject = singletonFactory.getObject();
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }
    return singletonObject;
}

先查一级缓存singletonObjects,

如果查到就返回,如果没查到并且当前正在创建的bean的beanName集合包含该beanName时,再查二级缓存earlySingletonObjects,

如果查到就返回,如果没查到再查三级缓存singletonFactories,

如果查到,将三级缓存的数据迁移到二级缓存,并返回。

如果最终从缓存中查到bean,直接return getObjectForBeanInstance()

2、getSingleton(()->createBean(beanName))

①当前正在创建的bean的beanName集合添加该beanName

②createBean()

③当前正在创建的bean的beanName集合删除该beanName

④将bean添加到一级缓存,并从二三级缓存中移除

3、return getObjectForBeanInstance()

如果beanName以 & 开头,返回该beanName的具体实例对象;

如果beanName不以 & 开头,且实现FactoryBean,返回getObject()的结果。

三、createBean()

1、InstantiationAwareBeanPostProcessor

遍历beanFactory的beanPostProcessors集合,如果实现InstantiationAwareBeanPostProcessor,调用postProcessBeforeInstantiation(),

如果方法返回值不是null,说明bean已经获取到,再遍历beanFactory的beanPostProcessors集合,分别调用postProcessAfterInitialization(),返回该bean,不走doCreateBean(),逻辑结束。

2、doCreateBean()

四、doCreateBean()

1、createBeanInstance()

如果beanDefinition 的 instanceSupplier不为空,调用instanceSupplier 的 get()方法创建bean;

否则通过反射获取构造函数对象,再调用newInstance()创建bean,

如果是有参构造函数,会通过beanFactory 的 getBean() 获取参数类型的bean,获取失败后抛异常。

2、放入三级缓存

如果当前正在创建的bean的beanName集合含有该beanName,并支持循环依赖,

则提前将该bean实例放入到三级缓存singletonFactories,其中getObject()中,会遍历beanFactory 的 beanPostProcessors集合,

如果实现SmartInstantiationAwareBeanPostProcessor,调用getEarlyBeanReference()作为getObject()方法的返回值。

3、populateBean()

该步骤主要用于为属性赋值。

①遍历beanFactory 的 beanPostProcessors集合,如果实现InstantiationAwareBeanPostProcessor,调用其postProcessAfterInstantiation()方法,如果返回值为false,populateBean()方法逻辑结束。

②遍历beanFactory 的 beanPostProcessors集合,如果实现InstantiationAwareBeanPostProcessor,调用其postProcessProperties()为属性赋值,其中有两个非常重要的InstantiationAwareBeanPostProcessor:分别是commonAnnotationBeanPostProcessor以及autowiredAnnotationBeanPostProcessor,commonAnnotationBeanPostProcessor的postProcessProperties()中会判断属性上是否含有@Resource注解,如果有会通过反射 field.set(bean, 属性类型bean) 为属性赋值;autowiredAnnotationBeanPostProcessor的postProcessProperties()中会判断属性上是否含有@Autowired注解,如果有会通过反射 field.set(bean, 属性类型bean) 为属性赋值。其中属性类型的bean的获取方式是通过beanFactory 的 getBean() 获取属性类型的bean,获取失败后抛异常。

4、initializeBean()

①invokeAwareMethods(),判断bean是否实现相应aware接口,如实现BeanNameAware,会调用setBeanName()方法,方法参数是beanName;实现BeanFactoryAware,会调用setBeanFactory()方法,方法参数是defaultListableBeanFactory。

②applyBeanPostProcessorsBeforeInitialization(),遍历beanFactory 的 beanPostProcessors集合,分别调用postProcessBeforeInitialization()方法,方法返回值作为bean。

③invokeInitMethods(),如果bean实现InitializingBean,调用afterPropertiesSet()方法。

④applyBeanPostProcessorsAfterInitialization(),遍历beanFactory 的 beanPostProcessors集合,分别调用postProcessAfterInitialization()方法,方法返回值作为bean。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MicoZone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值