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<T> {

@Nullable
T getObject() throws Exception;

@Nullable
Class<?> getObjectType();

default boolean isSingleton() {
    return true;
}
}



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

@FunctionalInterface
public interface ObjectFactory<T> {
/**
 * 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;

}


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信息的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,678评论 19 139
  • 什么是Spring Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Jav...
    jemmm阅读 16,780评论 1 133
  • 以前我不知道 瑀瑀独行这个成语 究竟 有怎样的含义 而现在 仍然是不知阿
    温言_f780阅读 162评论 0 0

友情链接更多精彩内容