Skip to the content.

Spring的版本是 5.2.6.RELEASE

spring-boot-starter-parent的版本是 2.3.0.RELEASE

要学习IOC流程,自然是从 AbstractApplicationContext类的refresh方法开始,这是IOC容器初始化的骨架方法。

refresh()

// AbstractApplicationContext.java 516
public void refresh() throws BeansException, IllegalStateException {
    //加个锁,确保在你构建这个容器的时候别人不能销毁或者重新构建这个容器
    synchronized(this.startupShutdownMonitor) {

        //准备工作:记录现在时间、设置容器状态为active、设置打印日志的方式、
        this.prepareRefresh();

        // 这个方法做两个事,生成BeanFactory还有将用户定义的Bean解析为BeanDefinition
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

        //准备工作:设置类加载器、添加BeanPostProcessor、注册系统bean、
        //确保存在Environment Bean,确保存在Properties Bean,确保存在SystemEnvironment Bean
        this.prepareBeanFactory(beanFactory);

        try {
            // 钩子方法
            this.postProcessBeanFactory(beanFactory);

            //调用BeanFactory所有子类的postProcessBeanFactory方法,这时候仅仅完成了注册还没初始化
            this.invokeBeanFactoryPostProcessors(beanFactory);

            //注册BeanPostProcessor
            this.registerBeanPostProcessors(beanFactory);

            // 以后来分析
            this.initMessageSource();

            //创建Spring的事件广播器。
            // 详细解析见:https://zimingsir.com/spring/Spring事件广播源码分析.html
            this.initApplicationEventMulticaster();

            // 模板方法
            this.onRefresh();

            //给事件广播器注册监听者,并且广播之前存储下来的事件。
            //详细解析见:https://zimingsir.com/spring/Spring事件广播源码分析.html
            this.registerListeners();

            //初始化所有的bean
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var9) {...} 
        finally {
            this.resetCommonCaches();
        }

    }
}

总结一下大致做了这样几件事。

obtainFreshBeanFactory

从IOC的refresh方法进入到obtainFreshBeanFactory()


// AbstractRefreshableApplicationContext 123
@Override
protected final void refreshBeanFactory() throws BeansException {
    
    //如果这个ApplicationContext已经存在
   if (hasBeanFactory()) {

      //销毁所有的单例Bean
      destroyBeans();

      //将BeanFactory变量指向一个null,序列化id设置为null
      closeBeanFactory();
   }
   try {

      //相当于new,不过多设置一个父BeanFactory,以后要一直使用这个DefaultListableBeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());

      //允许Bean重写,允许Bean循环依赖
      customizeBeanFactory(beanFactory);

      //解析各种形式定义的bean为BeanDefinition,并注册到beanFactory中。
      //后续会分析解析XML和解析注解的源码
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {...}
}

loadBeanDefinitions()加载BeanDefinition大致有两种实现。

通过注解加载BeanDefinition:// 另一篇文章

通过XML加载BeanDefinition:Spring从XML加载BeanDefinition源码分析

为了让当前文章的思路清晰,因此将上述两个加载流程的分析分别放到两篇文章。

当前我们只需要明白loadBeanDefinitions()方法就是将我们配置的Bean加载成BeanDefinition就可以。

Bean初始化

// AbstractApplicationContext.java 850
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化conversion bean。这个东西是用来做转换的,不太熟悉
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);
    beanFactory.freezeConfiguration();

    // 加载所有非延迟加载的单例Bean
    beanFactory.preInstantiateSingletons();
}

// DefaultListableBeanFactory.java 911
@Override
public void preInstantiateSingletons() throws BeansException {
    
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 去初始化所有的非延迟加载的单例Bean,当然也是非抽象的
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {...}
            else {
                getBean(beanName);
            }
        }
    }

    // 如果bean继承自SmartInitializingSingleton,还得回调一下afterSingletonsInstantiated()这个方法
    for (String beanName : beanNames) {...}
}

上面就是遍历所有beanName去初始化

生成Bean

// AbstractBeanFactory.java 201
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

// AbstractBeanFactory.java 248
protected <T> T doGetBean(String name, ...) throws BeansException {

    // 如果传的是别名或者FactoryBean需要先转换成对应的beanName
    String beanName = transformedBeanName(name);
    Object beanInstance;

    // 从缓存中获取单例Bean
    Object sharedInstance = getSingleton(beanName);

    // 如果从缓存中拿到了直接返回
    if (sharedInstance != null && args == null) {

        // 如果是FactoryBean则返回它生产的那个Bean
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // 如果Bean是Property类型且正在创建中,说明发生了循环依赖。
        // 这种情况的循环依赖Spring无法解决,因此抛出异常。
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
        BeanFactory parentBeanFactory = getParentBeanFactory();

        // 父BeanFactory存在 && beanName不在当前的BeanFactory中,那么就去父BeanFactory中获取
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {...}

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {

            // 获取合并后的BeanDefinition
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 获取当前BeanDefinition依赖的BeanDefinition
            String[] dependsOn = mbd.getDependsOn();

            // 如果依赖了别的BeanDefinition,那么先将依赖的BeanDefinition全部创建好
            if (dependsOn != null) {...}

            // 依赖的BeanDefinition创建好了之后,开始创建当前的

            // 如果当前是单例
            if (mbd.isSingleton()) {

                // 这是首先执行 getSingleton 方法
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                // 普通的Bean什么也不做直接返回,如果是BeanFactory,返回它生产的类。
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            else if (mbd.isPrototype()) {...}

            else {...}
        }
        catch (BeansException ex) {...}
        finally {
            beanCreation.end();
        }
    }

    // 检查Bean的类型是否对应
    return adaptBeanInstance(name, beanInstance, requiredType);
}

上面这一段逻辑就是:

首先去转换beanName的名称。

接着去缓存里面拿,如果拿到了那就返回。

如果没有拿到那就生成一个然后返回。

// DefaultSingletonBeanRegistry.java 214
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    // 锁住缓存
    synchronized (this.singletonObjects) {
        // 尝试从缓存中获取beanName
        Object singletonObject = this.singletonObjects.get(beanName);

        // 如果没有从缓存中拿到那就创建
        if (singletonObject == null) {

            // 将beanName加入到正在创建的beanName的集合中
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;

            try {
                // 调用 createBean 去创建Bean
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {...}
            finally {
                // 将beanName从正在创建的beanName的集合中移除
                afterSingletonCreation(beanName);
            }

            // 如果是从新创建的,那就加入到缓存中
            if (newSingleton) {
                addSingleton(beanName, singletonObject);
            }
        }

        // 如果从缓存中拿到了那就用缓存的,否则就从新创建一个然后返回
        return singletonObject;
    }
}

singletonObjects 是一级缓存,它存储的已经完成实例化、填充数据、初始化的单例Bean。

如果一个缓存这没有拿到对象,那就需要创建一个了。

将当前bean加入到正在创建中。

创建当前bean。

移除标记。

加入到一级缓存中。


// AbstractAutowireCapableBeanFactory.java 485
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    RootBeanDefinition mbdToUse = mbd;
    
    try {
        // 让 InstantiationAwareBeanPostProcessor 在这里有机会返回代理对象,如果返回了对象,方法就直接返回了。
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {...}

    try {
        // 创建Bean
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);

        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {...}
    catch (Throwable ex) {...}
}

给InstantiationAwareBeanPostProcessor一个返回对象的机会,如果不需要,那就我们创建Bean。


// AbstractAutowireCapableBeanFactory.java 555
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 实例化Bean
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }

    // 提前暴露:实例化之后就将Bean放到第三级的缓存 singletonFactories 中。
    // 后面需要get这个Bean的时候就可以从第三级缓存中拿到了。
    // 当前还没有发生循环依赖,这只是第一次创建,这是为了解决后续可能的循环依赖而做的操作。
    // 第三个判断的 beanName 在前面的 DefaultSingletonBeanRegistry.java 227行加入到了列表中
    //                             当前Bean为单例Bean &&      允许循环依赖             &&     当前单例Bean正在创建中(发生了循环依赖)
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        // 将Bean加入到三级缓存
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        // 填充 Bean 内部的属性。循环依赖就是 A - B 之间的相互引用,那就是从这个方法开始的。
        populateBean(beanName, mbd, instanceWrapper);

        // 初始化
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {...}

    if (earlySingletonExposure) {...}

    return exposedObject;
}

首先实例化Bean,接着填充Bean中的属性,然后是初始化Bean。


// 初始化
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用所有 BeanPostProcessor 的前置方法。所有的 BeanPostProcessor 都在 refresh 方法里面被注册了.
        // AbstractApplicationContext.java 567
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 前面是实例化和填充属性,现在是初始化。
        // 调用 InitializingBean 的 afterProperties 方法和 init-method xml 标签的方法。
        // 题外话:Dubbo的 ServiceBean 的暴露用的就是 afterProperties 方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor的后置方法
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

初始化就是BeanPostProcessor的前后钩子方法中间包着一个初始化。

初始化先调用 InitializingBean的afterPropertiesSet方法,接着调用init-method XMl 标签的方法。

学习IOC过程中收获很多的文章

https://www.javadoop.com/post/spring-ioc 对IOC的整体流程有一个较好的认识

https://blog.csdn.net/cristianoxm/article/details/107311570 通过这个文章学会了Spring是如何解析注解的。