Spring源码解析(八)-创建单例bean

Spring版本

5.2.5.RELEASE

参考

Spring-IOC-容器源码分析-创建单例-bean

源码解析

在上一篇《Spring源码解析-获取单例bean》中,在doGetBean的最后,调用了getSingleton方法,并且将beanName和一个返回createBean方法的匿名方法作为参数传入:

sharedInstance = getSingleton(beanName, () -> {
    try {
        return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
        // Explicitly remove instance from singleton cache: It might have been put there
        // eagerly by the creation process, to allow for circular reference resolution.
        // Also remove any beans that received a temporary reference to the bean.
        // 在早期的创建过程中,可能为了解决循环引用问题,导致beanName加入了singleton缓存中,此时需要移除该缓存
        destroySingleton(beanName);
        throw ex;
    }
});

那么我们先看看getSingleton方法

1. DefaultSingletonBeanRegistry#getSingleton

    public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            // 从缓存中获取
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                // 写入singletonsCurrentlyInCreation
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    // 这里的getObject方法实际上调用的是singletonFactory匿名函数的createBean方法
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    // createBean方法有可能抛出ImplicitlyAppearedSingletonException异常
                    // 该异常是IllegalStateException的子类,当这种异常出现的时候,此时bean可能已经被隐含地(implicitly)实例化
                    // 所以这一步需要再从singletonObjects这个已实例化的集合汇总获取一次实例化对象
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    // 从singletonsCurrentlyInCreation移除
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    // 针对singleton做一些缓存方面的处理,如加入的缓存、从早起引用map中移除等
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

首先从缓存中获取bean实例,如果存在,直接返回,否则进行创建的流程。
这里面入参singletonFactory是一个函数式接口参数:

@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;

}

因此,singletonFactory.getObject()实际上就是调用createBean方法

2. AbstractAutowireCapableBeanFactory#createBean

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

        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        // 确认到了这一步bean类型已经被解析,以防动态解析class的情况下,mdb的beanClass属性为空
        Class resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            // 处理look-up method和replace method
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // 看英文注释这里是给BeanPostProcessors一个机会返回一个代理对象而不是bean实例
            // 但是resolveBeforeInstantiation内部代码感觉又没有进去执行具体逻辑,具体后面解析
            // TODO
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        try {
            // 真正创建bean实例
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

1、通过resolveBeanClass解析mdb的beanClass属性
2、处理了lookup-method和replace-method俩种注入,关于这俩种注入方法,可以戳:14--Spring lookup-method注入和replace-method注入(二)
3、通过resolveBeforeInstantiationBeanPostProcessor一个机会返回代理对象
4、最后调用了doCreateBean进行创建

2.1 AbstractAutowireCapableBeanFactory#resolveBeanClass

    @Nullable
    protected Class resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class... typesToMatch)
            throws CannotLoadBeanClassException {

        try {
            // 如果mbd已经解析出beanClass,直接返回
            if (mbd.hasBeanClass()) {
                return mbd.getBeanClass();
            }
            if (System.getSecurityManager() != null) {
                return AccessController.doPrivileged((PrivilegedExceptionAction>) () ->
                    doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
            }
            else {
                // 否则,进行解析逻辑
                return doResolveBeanClass(mbd, typesToMatch);
            }
        }
        catch (PrivilegedActionException pae) {
            ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
        }
        catch (ClassNotFoundException ex) {
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
        }
        catch (LinkageError err) {
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
        }
    }
  • mbd已经有beanClass,那么直接返回
  • 否则,调用doResolveBeanClass进行解析

2.2 AbstractAutowireCapableBeanFactory#doResolveBeanClass

    @Nullable
    private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch)
            throws ClassNotFoundException {

        ClassLoader beanClassLoader = getBeanClassLoader();
        ClassLoader dynamicLoader = beanClassLoader;
        boolean freshResolve = false;

        if (!ObjectUtils.isEmpty(typesToMatch)) {
            // When just doing type checks (i.e. not creating an actual instance yet),
            // use the specified temporary class loader (e.g. in a weaving scenario).
            ClassLoader tempClassLoader = getTempClassLoader();
            if (tempClassLoader != null) {
                dynamicLoader = tempClassLoader;
                freshResolve = true;
                if (tempClassLoader instanceof DecoratingClassLoader) {
                    DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                    for (Class typeToMatch : typesToMatch) {
                        dcl.excludeClass(typeToMatch.getName());
                    }
                }
            }
        }

        // 获取文本类型的className,通过className和classLoader来获取beanClass
        String className = mbd.getBeanClassName();
        if (className != null) {
            // 貌似是解析SPEL表达式的,这块没看懂
            Object evaluated = evaluateBeanDefinitionString(className, mbd);
            // 如果俩者不相同,说明使用了SPEL表达式
            if (!className.equals(evaluated)) {
                // A dynamically resolved expression, supported as of 4.2...
                if (evaluated instanceof Class) {
                    return (Class) evaluated;
                }
                else if (evaluated instanceof String) {
                    className = (String) evaluated;
                    freshResolve = true;
                }
                else {
                    throw new IllegalStateException("Invalid class name expression result: " + evaluated);
                }
            }
            if (freshResolve) {
                // When resolving against a temporary class loader, exit early in order
                // to avoid storing the resolved Class in the bean definition.
                if (dynamicLoader != null) {
                    try {
                        // dynamicLoader不为空,通过dynamicLoader
                        return dynamicLoader.loadClass(className);
                    }
                    catch (ClassNotFoundException ex) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                        }
                    }
                }
                // 如果dynamicLoader为空,通过forName进行加载
                return ClassUtils.forName(className, dynamicLoader);
            }
        }

        // Resolve regularly, caching the result in the BeanDefinition...
        // 如果className为空,进行常规加载(该方法内部其实也是通过ClassUtils.forName(className, classLoader))
        return mbd.resolveBeanClass(beanClassLoader);
    }

获取string类型的className,加载获得对应的class

1.3 AbstractAutowireCapableBeanFactory#doCreateBean

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

        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        // 单例模型,则从未完成的 FactoryBean 缓存中删除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        // 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
        if (instanceWrapper == null) {
            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.
        // 判断是否需要应用后置处理器
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    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.
        // 这里是早期引用的逻辑,用于解决单例模式的循环引用,需要满足一下三个条件:
        // 1、单例模式
        // 2、开启早期引用
        // 3、beanName正在创建中(A依赖B,B依赖A,先创建A,发现依赖B,去创建B,结果发现依赖A,又再去创建A)
        // 第三点解释如下:
        // 情景:A依赖B,B依赖A
        // 过程:
        // 1、创建A,走到这一步,A没有处于创建中,earlySingletonExposure此时为false,继续往下走,将A正在创建中写入singletonsCurrentlyInCreation
        // 2、发现依赖B,去创建B
        // 3、创建B,走到这一步,B也没有处于创建中,同步骤一继续往下走
        // 4、发现依赖A,去创建A
        // 5、创建A,此时,A已经处于singletonsCurrentlyInCreation了,此时满足条件,进入if分支
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            // 解决循环引用,提前将bean实例写入singletonFactories、earlySingletonObjects和registeredSingletons
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // 填充属性
            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) {
            // addSingletonFactory中已经将bean加入earlySingletonObjects中,这里从中获取
            Object earlySingletonReference = getSingleton(beanName, false);
            // 只有循环依赖的情况下if分支的条件才会成立
            if (earlySingletonReference != null) {
                // exposedObject初始赋值便是bean,那么说明其没有被initializeBean方法改变
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                // allowRawInjectionDespiteWrapping:是否在循环依赖的情况下重新整理成原生bean
                // 个人理解是为了解决循环依赖问题,之前使用了早期引用,
                // 而一旦allowRawInjectionDespiteWrapping为true,那么就将该早期引用替换成原声bean
                // 不过这里的allowRawInjectionDespiteWrapping是false的情况下else if分支成立
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        // alreadyCreated 不包含dependentBean的情况下if分支成立
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    // 如果alreadyCreated包含任何一个dependentBean,那么这里if分支成立,此时抛出异常
                    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.
        try {
            // 注册bean销毁逻辑
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

1、使用createBeanInstance创建一个instanceWrapper,详见《Spring源码解析(九)-创建bean实例》
2、应用后置BeanPostProcessor
3、解决单例模式下循环引用的问题
4、通过populateBean填充属性,详见《Spring源码解析(十)-填充bean属性》
5、通过initializeBean应用init-method方法,详见《Spring源码解析(十一)-初始化bean》
6、实例化depends on对应的bean
7、调用registerDisposableBeanIfNecessary注册bean的销毁逻辑,详见《Spring源码解析(十二)-注册bean销毁逻辑》
8、返回创建完毕的bean实例

总结

创建单例bean的核心都在doCreateBean方法中,该方法分别实现了创建bean实例、应用BeanPostProcessors、解决循环引用问题、填充bean属性、应用init-method方法、实例化depends on对应的bean和注册bean销毁逻辑等功能,内容较多,需要逐个慢慢解析击破

你可能感兴趣的:(Spring源码解析(八)-创建单例bean)