Spring源码学习 | 4 Bean创建与初始化

275 阅读15分钟

前言

之前我们通过源码,了解了Spring XML配置文件中的<bean>是如何解析加载成为BeanDefinition的,所有的BeanDefinition都保存在beanFacotry当中。就好比beanFactory是一个工厂,BeanDefinition是产品的图纸,bean是工厂产品,解析过程就是把产品的图纸画了出来,接下来工厂就可以根据图纸开始生产产品了。

Bean创建与初始化

Spring对非懒加载的单例对象初始化是在容器初始化时完成的。我们还是以XmlWebApplicationContext为例,从refresh()方法看起。

AbstractApplicationContext

refresh()方法调用finishBeanFactoryInitialization(beanFactory)开始对单例对象初始化。在这一步会做一些准备操作;同时会冻结所有BeanDefinition,避免过程中BeanDefinition被修改;然后调用beanFacotry方法,让工厂开始工作。

DefaultListableBeanFactory

马上开始实例化了,我们看到他是会把所有的beanDefinitionNames拿出来遍历,对非懒加载的单例对象进行实例化。这里还对FactoryBean进行了处理,对于FactoryBean中渴望初始化的,就提前在容器初始化时候初始化。在所有Bean初始化完成后,这个方法里还会对SmartInitializingSingleton类型的对象触发回调,这个不细说。

getBean(beanName)是创建、初始化Bean对象的核心代码,我们着重来看这个方法的实现。这个方法是父类AbstractBeanFactory的方法。

// DefaultListableBeanFactory.java
@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }
    
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 不是抽象类 且 是单例 且 非懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                                            getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                getBean(beanName);
            }
        }
    }

    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

AbstractBeanFactory

getBean(beanName)方法又调用了doGetBean()方法。在Spring中,do开头的方法一般都是真正干活的= =。这个方法比较长,一百五六十行。我们还是先捋一捋这个方法的逻辑

  • beanName处理
  • 先尝试从缓存中获取bean实例,若有则返回
  • 如果当前beanFacotry找不到beanName对应的BeanDefinition,尝试从父容器获取bean
  • 将beanName加入alreadyCreated集合中,表示这个beanName已经创建或马上创建
  • 对bean的depends-on属性进行处理,对depends-on的类进行创建并初始化
  • 创建初始化bean,返回bean

这个逻辑中还是没有具体讲怎么创建单例bean,只是一句创建初始化bean带过。不要急,接下来我们看getSingleton(beanName, singletonFactory)方法,看里面的具体逻辑。

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

protected <T> T doGetBean(
                String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
                throws BeansException {

    String beanName = transformedBeanName(name);
    Object bean;

    // 尝试从三级缓存中获取bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                                    "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
        }

        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 如果当前beanFacotry找不到beanName对应的BeanDefinition,尝试从父容器获取
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                                nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

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

        try {
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 处理depends-on属性,对depends-on的创建并初始化
            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);
                    }
                }
            }

            // 创建单例对象
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            // 创建原型对象
            else if (mbd.isPrototype()) {
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                }
                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;
        }
    }

    // 这里getBean是传入为null,暂先不考虑这里
    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) {
            if (logger.isTraceEnabled()) {
                logger.trace("Failed to convert bean '" + name + "' to required type '" +
                                    ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

DefaultSingletonBeanRegistry

这个方法的入参是beanName和一个ObjectFactory。我们先看这个方法的逻辑

  • 尝试从一级缓存singletonObjects获取,若有则返回,若无则创建
  • 创建之前,把beanName加入singletonsCurrentlyInCreation集合,表示这个bean在创建中
  • 调用ObjectFactory,获取单例实例
  • 单例bean已经创建完成,会把beanName从singletonsCurrentlyInCreation移除
  • 新创建的单例对象放入缓存中
    • 放入一级缓存
    • 从二级缓存、三级缓存删除
// DefaultSingletonBeanRegistry.java
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);
        // 如果从singletonObjects中获取不到,则开始创建
        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 + "'");
            }
            // 这一步会把beanName加入singletonsCurrentlyInCreation集合,表示这个bean在创建中
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                // 调用ObjectFactory获取对象
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                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;
                }
                // 到这单例bean已经创建完成,会把beanName从singletonsCurrentlyInCreation移除
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                // 新创建的单例对象放入缓存中
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

protected void beforeSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

protected void afterSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

// 这个方法很关键。作用是单例对象放入缓存
protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        // 放入一级缓存
        this.singletonObjects.put(beanName, singletonObject);
        // 删除三级缓存
        this.singletonFactories.remove(beanName);
        // 淡出二级缓存
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

AbstractAutowireCapableBeanFactory

接下来我们着重看一下singletonFactory.getObject()。singletonFactory是ObjectFactory<?>类型的入参,AbstractApplicationContext在调用这个getSingleton方法时,传入的是一个匿名的对象,其中只有一个createBean()方法。这个方法的实现在AbstractAutowireCapableBeanFactory类,DefaultListableBeanFactory的父类。

image.png

这个方法可以看到住哟啊是一些准备工作,真正的工作是在doCreateBean()中。不过这里有一点注意,这个方法里通过调用resolveBeforeInstantiation()方法,给后置处理器一个可以返回代理对象的机会。如果返回的代理对象不为空,则返回,以这个代理对象来替代原来的bean。

// AbstractAutowireCapableBeanFactory.java
@Override
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;

    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 这里会调用InstantiationAwareBeanPostProcessor后置处理器
        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 {
        // 开始创建
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                        mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

来看看真正干活的doCreateBean()

  • 通过createBeanInstance()方法创建bean并包装在BeanWrapper中
    • 如果有Supplier,通过Supplier获取bean
    • 如果有factory-method,通过配置的factory-method获取bean
    • 解析构造方法、构造方法入参数
    • 选择构造函数,通过反射创建对象
    • 返回包装类
  • MergedBeanDefinitionPostProcessor后置处理器修改BeanDefinition
  • 判断是否通过三级缓存ObjectFactory提前暴露创建中的bean
    • 通过父类addSingletonFactory()方法放入三级缓存,并从二级缓存移除
  • 对创建的bean进行属性注入 以及初始化
  • 检查bean与二级缓存中被其他bean注入的是不是一个对象
  • 注册需要在销毁时有自定义操作的bean
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                throws BeanCreationException {

    // 实例化bean,包装在BeanWrapper中
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // MergedBeanDefinitionPostProcessor后置处理器修改BeanDefinition
    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;
        }
    }

    // 单例 且 允许循环引用 且 在创建中 => 通过三级缓存ObjectFactory提前暴露创建中的bean
    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");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // 对创建的bean进行属性注入 以及初始化
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        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);
        }
    }

    // 这里对提前暴露的情况进行检查,initializeBean()初始化方法之后的对象,是否与初始化之前的对象相同,
    // 如果是不同的对象,就对存在一个问题,就是其他bean注入的属性值和真正最终的bean不是同一各,就抛出异常 
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                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 " +
                                    "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // 注册需要在销毁时有自定义操作的bean
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

看一下实例化并创建包装对象的方法。主要逻辑是

  • 解析Class对象
  • 尝试应用Supplier、factory-method创建
  • 推断构造方法
  • 利用反射实例化并包装成BeanWrapper
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }
    
    // 如果有Supplier,通过Supplier获取bean
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 如果有factory-method,通过配置的factory-method获取bean
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // 这里主要是判断这个bean的构造器、构造器参数是否已经解析过,是不是可以直接用
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            return instantiateBean(beanName, mbd);
        }
    }

    // 这一块是关于构造函数、构造函数参数的解析、处理
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
                    
        return autowireConstructor(beanName, mbd, ctors, args);
    }
    
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // 使用无参构造函数
    return instantiateBean(beanName, mbd);
}

如果判断当前bean(允许循环依赖的创建中的单例对象)提前暴露的话,会将工厂类放到三级缓存中。

// DefaultSingletonBeanRegistry.java,是AbstractAutowireCapableBeanFactory的父类
// 允许循环依赖的单例对象提前暴露
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);
        }
    }
}

接着看下对象创建后的属性注入、初始化

// AbstractAutowireCapableBeanFactory.java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            return;
        }
    }

    // 给InstantiationAwareBeanPostProcessor一个机会,在属性注入之前可以对bean进行修改
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    // 根据Bean配置的依赖注入方式完成注入,默认是0,不走以下逻辑
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    // 是否有修改属性值的后置处理器
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 是否需要检查依赖。默认不需要
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    // 在属性值注入之前,给后置处理器修改属性值的机会
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    }
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        // 检查依赖
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        // 将属性值注入bean
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

后置处理器

在整个Bean加载的过程中,

1. Bean实例化之前

在bean实例化之前,允许InstantiationAwareBeanPostProcessor通过postProcessBeforeInstantiation()方法创建一个代理类,完全替换目标bean。如果代理类对象创建成功,则会调用所有后置处理器的postProcessAfterInitialization()方法,对代理类对象进行处理。然后直接返回,结束Bean的创建初始化。

image.png

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

   @Nullable
   default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   	return null;
   }
       
   default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
   	return true;
   }
       
   @Nullable
   default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
   	return null;
   }
       
   @Deprecated
   @Nullable
   default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
   	return pvs;
   }

}

2. 推断构造防范

在这里会使用调用SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors()方法,返回一个构造器数组。这里注意一下SmartInstantiationAwareBeanPostProcessor接口是继承于InstantiationAwareBeanPostProcessor。

image.png

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

    @Nullable
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    @Nullable
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }

}

3. MergedBeanDefinition处理

调用MergedBeanDefinitionPostProcessorpostProcessMergedBeanDefinition()方法。这里常见的几个实现类,有CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor,会扫描@PostConstruct、@Resource、@AutoWire等字段注解,然后将信息存入BeanDefinition,方便后续的依赖注入。在这xml配置bean的形式下,这一步作用其实比较有限。

image.png

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

    default void resetBeanDefinition(String beanName) { }
}

4. 三级缓存内工厂类提前暴露bean

这个真正执行时间应该是尝试从三级缓存singletonFactories获取bean时调用的。从三级缓存取出的是一个ObjectFactory,它会通过SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference()方法来获取提前暴露的未初始化完全的bean。

从上面SmartInstantiationAwareBeanPostProcessor源码可知,默认提前暴露的就是bean自己,没有额外操作。

image.png

5. 属性填充之前自定义属性填充

在bean准备开始属性填充的时候,Spring允许我们通过InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation()方法,自定义进行属性注入。这个方法的返回类型是boolean,返回时false的时候,就直接结束属性填充,不走Spring属性填充的逻辑了。

image.png

6. 修改属性值

在获取属性值之后,注入之前,还有一次机会修改属性值。InstantiationAwareBeanPostProcessor提供了postProcessProperties()方法。

image.png

7. 初始化前应用所有BeanPostProcessor

到这一步bean的属性已经注入了,aware接口也已经处理完成了,接下来进行初始化操作。在这一步,所有的后置处理器的postProcessBeforeInitialization()方法都会被调用

image.png

image.png

8. 初始化后应用所有BeanPostProcessor

bean所有的初始化方法都执行完了,整个bean其实就算是创建完了。这时候所有后置处理器的postProcessAfterInitialization()会被调用

image.png

image.png

9. 注册销毁方法

到这bean所有的操作都几乎完成了,还有就是注册销毁方法。DestructionAwareBeanPostProcessor的源码简单看下。

image.png

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

    default boolean requiresDestruction(Object bean) {
            return true;
    }

}

循环依赖

有些观点认为,如果代码中出现了循环依赖,那么说明代码的设计是有些糟糕的。但是Spring没有完全堵死这条路,它是允许出现循环依赖的。

提前曝光

例如有OneComponent和TwoComponent两个相互依赖的类。

@Component
public class OneComponent {
    @Autowired
    private TwoComponent twoComponent;
}

@Component
public class TwoComponent {
    @Autowired
    private OneComponent oneComponent;
}

那我们考虑一下循环依赖最核心的问题无非是,我TwoComponent进行属性注入的时候,我拿不到你OneComponent的bead的引用。那只要能提前拿到引用,问题其实就解决了。那我可以通过一个专门存创建完的bean的缓存(singletonObjects);再来一个专门存没有创建完的bean的缓存(earlySingletonObjects),提前曝光,那这个问题不就解决了么?

未命名文件.jpg

三级缓存

上面这个流程图一看,好像是没啥毛病。但是其实Spring是采用了三级缓存来解决循环依赖

  • singletonObjects:一级缓存,存放完全的bean
  • earlySingletonObjects:二级缓存,存放尚未完全的bean
  • singletonFactories:三级缓存,存放产生bean的ObjectFactory

image.png

为什么需要再设计一个singletonFactories缓存? 其实,三级缓存的设计主要是配合Spring的AOP特性

对于一般的单例对象,AOP都是在初始化方法完成之后,再应用AbstractAutoProxyCreator中的postProcessAfterInitialization()方法。但是,对于因为循环依赖而需要提前曝光的单例来说,如果只有两季缓存就有些问题了。

我们知道属性注入是在初始化方法之前的,那么当然也在AOP之前。只有两级缓存的情况下,我TwoComponent进行属性注入,从二级缓存中取出的是就是OneComponent在AOP之前的bean。TwoComponent的bean所有步骤都完成了,进入了一级缓存,然后TwoComponent的bean开始属性注入、初始化方法调用、AOP返回代理对象,最终bean也进入一级缓存。注意,问题来了。TwoComponent的属性注入的是OneComponent原始的单例对象bean,而最终OneComponent对应的真正的单例对象是经过AOP之后的代理对象bean,这俩根本不是一回事。

所以为了解决这个问题,引入了singletonFactories缓存。这个缓存存的是单例对象对应的ObjectFactory对象,ObjectFactory对象会调用SmartInstantiationAwareBeanPostProcessor实现类的getEarlyBeanReference()方法,来产生提前曝光的引用。

image.png

image.png

不需要AOP的单例对象,会这一步直接返回bean本身;需要AOP的单例对象,在这一步则会通过调用AbstractAutoProxyCreator的getEarlyBeanReference()方法提前产生代理对象。 这样可以就可以避免AOP之后的代理对象与原单例对象不相同的问题。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    // 省略...
    
    // 需要AOP的单例对象调用,提前产生代理对象,供提前曝光
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 记录提前代理的bean
            this.earlyProxyReferences.add(cacheKey);
        }
        return wrapIfNecessary(bean, beanName, cacheKey);
    }

    // 省略...
    
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // 判断是否提前代理
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                // 未提前代理,当前对象如果需要代理类则创建代理类
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
    
    // 省略...
}

来整理一下循环依赖的流程,还是以OneComponent和TwoComponent为例

  • 尝试从缓存获取OneComponent对应的bean
  • 缓存中无,则开始创建OneComponent实例
  • 提前曝光到三级缓存
  • 对创建的bean进行属性注入
    • 尝试从缓存获取TwoComponent对应的bean
    • 缓存中无,则开始创建TwoComponent实例
    • 提前曝光到三级缓存
    • 对TwoComponent实例进行属性注入
    • 从三级缓存获取到提前曝光的OneComponent实例(有AOP则是获取到代理对象)注入并转入二级缓存
    • 初始化方法调用
    • 应用AOP(如果有的话)
    • TwoComponent对应的bean全部完成,放入一级缓存
  • 从一级缓存获取TwoComponent对应的bean,注入
  • 初始化方法调用
  • 应用AOP(如果有的话)
  • OneComponent对应的bean全部完成,放入一级缓存
  • 循环依赖的两个Bean操作结束

@Async引起的循环依赖异常

这里顺带提一下之前碰到的一个问题,@Async引起的循环依赖异常。这个也有代理,但是为啥三级缓存解决不了呢?简单说下吧,关键是getEarlyBeanReference()方法。@Async是由AsyncAnnotationBeanPostProcessor处理的,没有像处理AOP的AbstractAutoProxyCreator那样,实现SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference()方法,导致无法提前暴露代理对象,导致注入和最终的对象不一致,抛出异常。

结语

这篇文章写的东西比较多,比较杂也比较难。后面有时间有重新整理一下。先看下图回顾下Bean创建与初始化的整体流程吧。

image.png