Spring IOC源码读后记录

首先弄清楚Spring在这一部分涉及的一些类和接口:
BeanFactory和ApplicationContext:都是用来加载bean的,但是ApplicationContext包含了BeanFactory的所有功能并添加了许多扩展功能,比如容器后处理器、Bean后处理器、注册监听器等等。

public interface BeanFactory {
Object getBean(String name, ...) throws BeansException;
     ... ...
}



FactoryBean:Spring默认通过反射的方式来创建Bean实例,但是用户可以通过自己定义实现FactoryBean方法来自定义实例的创建方式。

public interface FactoryBean {

@Nullable
T getObject() throws Exception;

@Nullable
Class getObjectType();

default boolean isSingleton() {
    return true;
}
}



ObjectFactory:通过它的getObject方法可以获取bean实例,这是用来解决循环依赖的。在循环依赖解决的代码中,它的getObject方法返回的是一个Bean的EarlyReference。

@FunctionalInterface
public interface ObjectFactory {
/**
 * Return an instance (possibly shared or independent)
 * of the object managed by this factory.
 * @return the resulting instance
 * @throws BeansException in case of creation errors
 */
T getObject() throws BeansException;

}


Spring IOC源码读后记录_第1张图片
image.png

Getbean方法:
1、 通过beanName从缓存加载bean,若为空,转2.
2、 加载创建bean:
2.1原型bean的循环依赖检查
2.2 获取beanDefinition对象,递归实例化依赖对象
2.3 根据不同的scope创建bean(默认通过反射来实例化bean,也可以通过实现FactoryBean接口来自定义实例化方式)。

从缓存中加载bean的步骤:
1、 从singletonObjects获取,没有转2
2、 从earlySingletonObjects中获取,获取不到转3
3、 从singletonFactories中获取,若获取到,则调用singleton Factory.getObject()获取bean返回并将该bean放入earlySingletonObjects中。

创建bean步骤:
1、 创建bean
2、 addSingletonFactory:这一步是解决循环依赖的关键,这样下一步填充属性的时如果发生循环依赖,那就可以从singletonFactories获取到还没创建完成的bean。
3、 填充属性
4、 其他

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName,
             () -> getEarlyBeanReference(beanName, mbd, bean));  *********
    }

//可以看出addSingletonFactory方法就是在singletonFactories集合中放入了该bean对应的ObjectFactory。
protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);   ***********
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

Spring循环依赖解决方法:
三个缓存map:singletonObjects存放单例bean、singletonFactories存放创建Bean工厂对象、earlySingletonObjects存放创建中的Bean。
创建Bean的时候,若bean为单例且允许循环依赖的话就会提前创建一个该bean的ObjectFactory对象放入singletonFactories中(即addSingletonFactory())。所以创建其他bean的时候若依赖该bean,是可以从singletonFactories获取到该bean信息的。

你可能感兴趣的:(Spring IOC源码读后记录)