美文网首页
Spring IOC源码读后记录

Spring IOC源码读后记录

作者: 柚子过来 | 来源:发表于2018-03-05 17:44 被阅读0次

    首先弄清楚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信息的。

    相关文章

      网友评论

          本文标题:Spring IOC源码读后记录

          本文链接:https://www.haomeiwen.com/subject/livhfftx.html