SpringIoc源码(十五)- BeanFactory(四)- getBean(上)

天大地大妈咪最大 提交于 2019-12-18 20:37:59

目录

1、获取真实的BeanName(传入的可能是别名等)

2、从缓存中获取实例(如果已经调用过getBean)


    之所以先写了ApplicationContext的refresh方法再写继续写BeanFactory的getBean核心方法,是因为觉得项目中根本不会直接使用BeanFactory肯定还是会使用ApplicationContext。并且每个Bean的生命周期会在getBean中完成,其中就会回调所有的BeanPostProcessorpostProcessBeforeInitializationpostProcessAfterInitialization方法。

    先梳理一下getBean的整个过程(只分析单利Bean)

    1、首先会从缓存中获取;否则(第一次)需要根据之前注入的BeanDefinition进行创建。

    2、创建之前需要先处理ovverride和前置准备;在创建时会有依赖注入的情况(需要解决循环依赖的问题),则再分析真正的创建

    3、创建过程:创建Bean实例;记录创建Bean的工厂;属性注入;初始化Bean(Bean的生命周期在这里完成,包括注册DisposableBean)

    开始:

@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
    @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    // 省略
}

1、获取真实的BeanName(传入的可能是别名等)

    调用getBean方法时候,传入的字符串可能是别名,或者是FactoryBean类型则可能传入&开头的,以获取FactoryBean本身。所以需要考虑各种情况,拿到真是的bean名称。    

 

2、从缓存中获取实例(如果已经调用过getBean)

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

    如果第一次调用getBean初始化完成后,则会将实例化的Bean放入DefaultSingletonBeanRegistrysingletonObjects容器中;为了解决单利循环依赖的问题,则在依赖注入时,会提前将未完成的Bean提前放入earlySingletonObjects容器中。创建Bean的工厂与Bean名称的关系存储在singletonFactories容器中。

    1、先直接先看是否初始化完成,如果没有拿到,则判断是否正在创建中。

    2、如果是则从earlySingletonObjects中进行获取。并且当前allowEarlyReference参数为true,则如果正在依赖注入创建中,直接从工厂中获取

    3、如果工厂已经存在,则直接getBean调用工厂的getBean方法,并且提前暴露放到earlySingletonObjects中。

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!