Spring IOC容器启动源码分析

1. 引言


我们可以通过ApplicationContext创建IOC容器,它有很多个子类,下面通过它的子类AnnotationConfigApplicationContext的创建来分析下IOC容器是如何创建并进行初始化的。

ApplicationContext applicationContext = 
new AnnotationConfigApplicationContext(AopConfig.class);

AnnotationConfigApplicationContext创建的源码如下:

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
    this();
    register(annotatedClasses);
    refresh();
}

这里refresh()方法是重点,它的源码是:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();
        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);
        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            // Initialize message source for this context.
            initMessageSource();
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();
            // Initialize other special beans in specific context subclasses.
            onRefresh();
            // Check for listener beans and register them.
            registerListeners();
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
            // Last step: publish corresponding event.
            finishRefresh();
        } catch (BeansException ex) {
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
            // Reset 'active' flag.
            cancelRefresh(ex);
            // Propagate exception to caller.
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

refresh()方法中每一行都很重要,我们依次来进行分析。

2. prepareRefresh()


该方法主要是为IOC容器启动做一些准备工作,设置容器的启动时间,closedactive标识。

  protected void prepareRefresh() {
    // Switch to active.
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    

    // 空方法,留给子类扩展,初始化 placeholder property
    initPropertySources();

    // 验证一些必须的属性
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    } else {
        // Reset local application listeners to pre-refresh state.
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

这里有个可以扩展的点,我们可以通过重写ApplicationContext来对自定义环境变量验证,要求必须存在某个环境变量时才能启动IOC容器。具体细节可以参考:https://blog.csdn.net/boling_cavalry/article/details/81474340

3. obtainFreshBeanFactory


obtainFreshBeanFactory()主要是获取BeanFactory,在获取BeanFactory之前会先创建BeanFactory

先来看看BeanFactory是在什么地方创建的,我们回到AnnotationConfigApplicationContext创建的地方。

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
    this(); // 调用无参的构造
    register(annotatedClasses);
    refresh();
}

无参构造器默认会隐式地调用父类的无参构造器方法,AnnotationConfigApplicationContext的父类是GenericApplicationContext,而BeanFactory就是在GenericApplicationContext的构造方法中创建出来的。

public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

再回到obtainFreshBeanFactory()方法,它主要做了3件事情:

  1. 设置refreshed属性,通过AtomicBooleancas操作控制refresh()方法只会被调用一次;
  2. beanFactory设置serializationId
  3. 返回beanFactory对象,实际类型为DefaultListableBeanFactory

4.prepareBeanFactory


prepareBeanFactory(beanFactory)主要功能是给上一步获取到的beanFactory进行一些属性的设置。主要设置了以下属性:

  • BeanFactory的类加载器、支持表达式解析器;
  • 添加了两个BeanPostProcessorApplicationContextAwareProcessorApplicationListenerDetector
  • 设置忽略的自动装配接口:EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware, 在依赖注入的时候忽略这些接口,也就是这些指定的接口不会被注入进去。
  • 注册可以解析的自动装配:BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext,这些类可以在任何地方直接注入;
  • 添加类加载期织入(LoadTimeWeaver)的AspectJ
  • 注册一些组件:environmentsystemPropertiessystemEnvironment

在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入、类加载期织入和运行期织入。编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中;而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面;运行期织入则是采用CGLib工具或JDK动态代理进行切面的织入。

AspectJ提供了两种切面织入方式,第一种通过特殊编译器,在编译期,将AspectJ语言编写的切面类织入到Java类中,可以通过一个Ant或Maven任务来完成这个操作;第二种方式是类加载期织入,也简称为LTW(Load Time Weaving)。

5. postProcessBeanFactory


postProcessBeanFactory(beanFactory)是个空方法。子类可以通过重写这个方法,在BeanFactory创建并预准备完成之后做些扩展工作。该方法在spring-web下有对其进行重写。

6. invokeBeanFactoryPostProcessors


invokeBeanFactoryPostProcessors(beanFactory)主要用来执行BeanFactoryPostProcessors,它会将bean的信息转化成BeanDefinition

BeanFactoryPostProcessorsBeanFacotry的后置处理器,在BeanFactory标准初始化之后执行,它是Spring提供的众多扩展点之一。BeanFacotry后置处理器有两个接口:BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor

invokeBeanFactoryPostProcessors方法整体流程如下:

先执行`BeanDefinitionRegistryPostProcessor`接口:
1. 获取所有的`BeanDefinitionRegistryPostProcessor`;
2. 看先执行实现了`PriorityOrdered`优先级接口的`BeanDefinitionRegistryPostProcessor`、         `postProcessor.postProcessBeanDefinitionRegistry(registry)`
3. 在执行实现了`Ordered`顺序接口的`BeanDefinitionRegistryPostProcessor`;
`postProcessor.postProcessBeanDefinitionRegistry(registry)`
4. 最后执行没有实现任何优先级或者是顺序接口的`BeanDefinitionRegistryPostProcessors`;
`postProcessor.postProcessBeanDefinitionRegistry(registry)`
            
再执行`BeanFactoryPostProcessor`的方法
1. 获取所有的`BeanFactoryPostProcessor`
2. 看先执行实现了`PriorityOrdered`优先级接口的`BeanFactoryPostProcessor`、
`postProcessor.postProcessBeanFactory()`
3. 在执行实现了`Ordered`顺序接口的`BeanFactoryPostProcessor`;
`postProcessor.postProcessBeanFactory()`
4. 最后执行没有实现任何优先级或者是顺序接口的`BeanFactoryPostProcessor`;
`postProcessor.postProcessBeanFactory()`

7. registerBeanPostProcessors


registerBeanPostProcessors(beanFactory)方法用来向beanFactory注册BeanPostProcessor(bean的后置处理器),这又是Spring容器提供的众多扩展点之一。Bean的后置处理器共有5个接口:

  1. BeanPostProcessor
  2. DestructionAwareBeanPostProcessor
  3. InstantiationAwareBeanPostProcessor
  4. SmartInstantiationAwareBeanPostProcessor
  5. MergedBeanDefinitionPostProcessor

这5个接口中的方法会在IOC容器启动过程中不同的时机被回调。

BeanFacotryPostProcessor类似,BeanPostProcessor也能够通过实现PriorityOrderedOrdered接口进行排序。

registerBeanPostProcessors(beanFactory)方法中将BeanFacotryPostProcessor分成priorityOrderedPostProcessorsinternalPostProcessorsorderedPostProcessorNamesnonOrderedPostProcessorNames 4 类,分好类之后再依次添加BeanFactory中。

priorityOrderedPostProcessor: 实现了`PriorityOrdered`接口的BeanPostProcessor;
orderedPostProcessorNames: 实现了`Ordered`接口的BeanPostProcessor;
nonOrderedPostProcessorNames: 没有实现排序的BeanPostProcessor
internalPostProcessors: MergedBeanDefinitionPostProcessor接口

通过请求beanFactory.addBeanPostProcessor(postProcessor);方法,向容器中添加bean的后置处理器。

8. initMessageSource


initMessageSource()方法是向容器中注册一个MessageSource组件。MessageSource主要作用是支持国际化。

initMessageSource()方法的主要逻辑是:
先看容器中是否有namemessageSourceMessageSource的组件,

if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // Make MessageSource aware of parent MessageSource.
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                // Only set parent context as parent essageSource if no parent MessageSource
                // registered already.
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
}

如果容器中没有MessageSource组件,则创建出来并注册到beanFactory中。

DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);

9. initApplicationEventMulticaster


initApplicationEventMulticaster()主要对事件派发器(ApplicationEventMulticaster)进行初始化,即向beanFactory注册一个事件派发器。它的逻辑很很简单,就是先判断容器中是否有name=applicationEventMulticaster的bean,没有的话就创建一个再向容器中注册。

10. onRefresh


这个方法默认实现什么都没有做,主要留给子类进行拓展。

11. registerListeners


registerListeners() 将所有的ApplicationListener进行注册,并进行事件派发。它的主要逻辑:

  1. 获取所有的ApplicationListener
  2. 将每个监听器添加到事件派发器中;
  3. 如果存在早期应用事件,则将其发布出去。

12. finishBeanFactoryInitialization


finishBeanFactoryInitialization(beanFactory)是个重点方法,它会将所有非懒加载的单例对象进行实例化。

AbstractApplicationContext#finishBeanFactoryInitialization方法中,它最终会调用DefaultListableBeanFactory#preInstantiateSingletons方法对剩下的单实例bean进行初始化,我们重点看看此方法。先贴一下源码:

public void preInstantiateSingletons() throws BeansException {
    // beanDefinitionNames在refresh()之前创建ApplicationContext的this()方法中进行设值
    List beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 遍历触发所有非懒加载的单例bean进行初始化
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        //单例、非抽象、非懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // bean是否为工厂bean,工厂bean需要加
            if (isFactoryBean(beanName)) {
                // 通过 &+beanName来获取工厂bean本身,而beanName获取的是FactoryBean创建的对象
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean factory = (FactoryBean) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction)
                                        ((SmartFactoryBean) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        // 获取FactoryBean创建的bean对象
                        getBean(beanName);
                    }
                }
            }
            else {
                // 普通的单例bean获取对象,实际会进行初始化
                getBean(beanName);
            }
        }
    }

    // 触发实现了SmartInitializingSingleton接口的afterSingletonsInstantiated方法
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}
 
 

其中getBean()方法是重点,我们需要重点关注。getBean()是定义在AbstractBeanFactory类中的方法,getBean()方法最终会调用doGetBean()方法(Spring中很多类似的风格,真正干活的都放在doXxx方法中)。

doGetBean方法中会完成bean的初始化,其大概逻辑是:先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存到名为singletonObjects的map中),如果获取不到就进行Bean的创建流程,而在每个Bean创建的过程中又会触发各种BeanPostProcessor的执行。

12.1 获取bean-doGetBean


下面来看看doGetBean的源码:

protected  T doGetBean(final String name, @Nullable final Class requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    // beanName转换,因为传入的参数可以是alias,也可能是FactoryBean的name,所以需要进行转换
    final String beanName = transformedBeanName(name);
    Object bean;

    // 尝试从缓存中获取bean,这里缓存有三级缓存,主要用来解决循环依赖问题
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // 原型模式,如果存在循环依赖,则抛出异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 获取父BeanFactory
        BeanFactory parentBeanFactory = getParentBeanFactory();
        //如果当前容器中没有bean的定义信息,就从父容器中获取
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            } else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            } else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }
        // 如果不仅仅是做类型检查,标记bean的状态已经创建,即将beanName加入alreadyCreated集合中
        if (!typeCheckOnly) {
            // 这个方法使用了双重检测机制
            markBeanAsCreated(beanName);
        }

        try {
            // 如果存在父bean,则同时合并父bean的相关属性
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 检查bean是否是抽象的,是的话就抛出异常
            checkMergedBeanDefinition(mbd, beanName, args);

            // 加载当前bean依赖的bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 缓存依赖调用
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    } catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 处理单例bean
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 实际创建beand的地方
                        return createBean(beanName, mbd, args);
                    } catch (BeansException ex) {
                        // 从单例缓存中移除
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
                // scope==prototype的bean 创建新的实例.
                Object prototypeInstance = null;
                try {
                    // 设置正在创建的状态
                    beforePrototypeCreation(beanName);
                    // 创建bean
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                // 返回对应的实例
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                // 其他scope的bean
                String scopeName = mbd.getScope();
                // scope合法性校验
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        } finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        } catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // 如果对返回 bean 类型有要求,则进行类型检查,并按需做类型转换
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            // 执行类型转换,转换成期望的类型
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        } catch (TypeMismatchException ex) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

整个方法可以概括为:

1、转换Bean的名称,获取真正的beanName;
2、检查三级缓存中是否含有bean,如果含有则实例化并返回对象,否则继续流程;
3、如果当前beanFactory中不存在需要的bean,则从父容器中获取bean;
4、如果当前bean存在依赖的bean,就遍历初始化依赖的bean对象;
5、根据bean的作用域不同,对bean进行实例化,作用域分为:singleton、prototype和其他;
6、如果requiredType不为空,则做类型校验,如果需要类型和实际类型不一致,则做类型转换;
7、返回bean对象。

12.2 bean的创建--createBean

上面doGetBean方法中,创建bean的工作是调用AbstractAutowireCapableBeanFactory#createBean来完成的,以下是createBean的源码(省略日志输出和异常处理):

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    RootBeanDefinition mbdToUse = mbd;

    // 根据设置的class属性或className来解析得到Class引用
    Class resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // 处理lookup-method和replaced-method标签
    try {
        mbdToUse.prepareMethodOverrides();
    }

    // 处理InstantiationAwareBeanPostProcessor,让BeanPostProcessor先拦截返回代理对象
    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }

    // 创建bean实例
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
}

该方法虽然叫createBean,但还不是真正创建bean的地方,它主要还是在做一些前期的准备工作,具体创建bean的方法是doCreateBean。在看doCreateBean方法之前,会调用resolveBeforeInstantiation()方法。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // mbd是程序创建的且存在后置处理器
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            // 获取最终的class引用,如果是工厂方法则获取工厂所创建的实例类型
            Class targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 调用实例化前置处理
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 调用初始化后置处理
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

可以看到如果InstantiationAwareBeanPostProcessor中的实例化前置处理方法的返回值不为空,就会直接请求BeanPostProcessor接口中的初始化后置处理方法。而如果这个方法的最终返回值bean不为空,则会跳过后续的doCreateBean方法执行(因为bean已经创建完成了),从而形式短路。

12.2.1 doCreateBean

从上面的分析,我们知道:createBean只是在做创建bean之前的准备工作,真正创建bean的方法是doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {

    // 如果是单例,尝试获取对应的BeanWrapper.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // BeanWrapper为空,即bean未实例化,则创建bean实例
    if (instanceWrapper == null) {
        // 使用对应的策略(工厂方法、构造函数)创建bean实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    // 应用MergedBeanDefinitionPostProcessor
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 处理merged bean
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    // 检查是否需要提前暴露,避免循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        // 为避免循环依赖,在bean实例化完成之前,将对应的ObjectFactory添加到singletonFactories属性中
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // 初始化Bean实例.
    Object exposedObject = bean;
    try {
        // 对bean的属性进行填充,注入属性值
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化Bean,调用各种初始化方法
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }

    // 再次验证是否存在依赖关系
    if (earlySingletonExposure) {
        // 获取单例bean,不允许早期引用
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                // 获取依赖的bean name
                String[] dependentBeans = getDependentBeans(beanName);
                Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                // bean在创建完成之后,其依赖的bean一定是被创建了的
                // 如果actualDependentBeans不为空,则说明bean依赖的bean没有完成创建,存在循环依赖
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" +
                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                    "wrapped. This means that said other beans do not use the final version of the " +
                                    "bean. This is often the result of over-eager type matching - consider using " +
                                    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    // 注册DisposableBean
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

doCreateBean方法概括起来,主要分为以下步骤:

1)、`创建Bean实例`:createBeanInstance(beanName, mbd, args);利用工厂方法或者对象的构造器创建出Bean实例;
2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName):调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3)、检查是否需要提前曝光,避免循环依赖
4)、`Bean属性赋值`:populateBean(beanName, mbd, instanceWrapper);
    赋值之前:
    1)、调用InstantiationAwareBeanPostProcessor后置处理器的postProcessAfterInstantiation();
    2)、调用InstantiationAwareBeanPostProcessor后置处理器的postProcessPropertyValues();
    赋值之后:
    3)、应用Bean属性的值,为属性利用setter方法等进行赋值;
    applyPropertyValues(beanName, mbd, bw, pvs);
5)、`Bean初始化`:initializeBean(beanName, exposedObject, mbd);
    1)、【执行Aware接口方法】invokeAwareMethods(beanName, bean); 执行xxxAware接口的方法BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
    2)、【执行后置处理器postProcessBeforeInitialization】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); BeanPostProcessor.postProcessBeforeInitialization();
    3)、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
        1)、是否是InitializingBean接口的实现;执行接口规定的初始化;
        2)、是否自定义初始化方法;
    4)、【执行后置处理器postProcessAfterInitialization】applyBeanPostProcessorsAfterInitialization: BeanPostProcessor.postProcessAfterInitialization();
6)、再次验证是否存在循环依赖;
7)、注册 DisposableBean。

13.finishRefresh


finishRefresh()完成IOC容器的创建。

protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    clearResourceCaches();

    // 初始化一个和生命周期相关的后置处理器LifecycleProcessor,默认从容器中找,没找到就创建一个
    initLifecycleProcessor();

    // 回调LifecycleProcessor的onRefresh方法
    getLifecycleProcessor().onRefresh();

    // 发布容器刷新完成事件
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

至此,SpringIOC容器就创建完毕。

写了一天,有点写不动了。先这样吧,后续有精力再进行更新吧。

参考

https://my.oschina.net/wangzhenchao/blog/918237

你可能感兴趣的:(Spring IOC容器启动源码分析)