Spring IOC 源码之 createBean

151 阅读4分钟

前2篇文章主要介绍了getBeandoGetBean的过程,今天本文主要讲一下createBean,话不多说,先贴一下代码

1 createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

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

    try {
        // 2 验证覆盖方法
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 3 给 BeanPostProcessors 留一个后门
        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 {
        // 4 执行真正创建 bean 的过程
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("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 durig bean creation", ex);
        }
}
  1. 解析beanClass,如果获取的class 属性不为null,则克隆该 BeanDefinition并赋值,因为该动态解析的 class 无法保存到到共享的 BeanDefinition
  2. 验证覆盖方法 该操作其实只是验证下该bean中的方法是否被重载,如果未被重载,则进行标记
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    if (hasMethodOverrides()) {
        Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
        synchronized (overrides) {
            for (MethodOverride mo : overrides) {
                prepareMethodOverride(mo);
            }
        }
    }
}

protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    if (count == 0) {
        throw new BeanDefinitionValidationException(
                "Invalid method override: no method with name '" + mo.getMethodName() +
                "' on class [" + getBeanClassName() + "]");
    }
    else if (count == 1) {
        mo.setOverloaded(false);
    }
}

3.resolveBeforeInstantiation 实例化前置操作,核心方法为applyBeanPostProcessorsBeforeInstantiationapplyBeanPostProcessorsAfterInitialization

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            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;
}

2 doCreateBean

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

    // 1 声明 instanceWrapper
    BeanWrapper instanceWrapper = null;
    // 2 单例模型,则从未完成的 FactoryBean 缓存中删除
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }

    // 3 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }

    // 4 获取包装的实例对象,以及实例的class type
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }
    // 5 如果有后置处理,则允许后置处理修改 BeanDefinition
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 6 后置处理修改 BeanDefinition
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // 7 解决单例模式的循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
       
        // 8 提前将创建的 bean 实例加入到objectFactory 中,为了后期避免循环依赖
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    
    Object exposedObject = bean;
    try {
        // 9 对 bean 进行填充,将各个属性值注入,若依赖于其他 bean 的属性 则会递归初始依赖 bean
        populateBean(beanName, mbd, instanceWrapper);
        // 10 调用初始化方法
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        //抛出异常
    }

    //11 循环依赖处理,敲黑板
    if (earlySingletonExposure) {
        // 12 获取 earlySingletonReference
        Object earlySingletonReference = getSingleton(beanName, false);
        // 13 只有在存在循环依赖的情况下,earlySingletonReference 才不会为空
        if (earlySingletonReference != null) {
            // 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
            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) {
                    //这个判断主要看,那些依赖exposeObject的bean是不是已经在创建中了,如果是,则说明该exposeObject 已经注入到其他bean了
                    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 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }
    try {
        // 14 注册 bean
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

  1. 声明 instanceWrapper
  2. 如果是单例模式,则通过this.factoryBeanInstanceCache.remove(beanName) 获取instanceWrapper
  3. 如果此时instanceWrapper仍是null,则通过createBeanInstance()获取
  4. 获取包装的实例对象,以及实例的class type
  5. 同步锁加起来
  6. 后置处理修改 BeanDefinition
  7. 高能预警哈,后面就是解决循环依赖的地方啦!!!earlySingletonExposure 标志是否可以提前暴露,前提是 单例, 允许循环依赖,该bean正在创建过程中
  8. 提前将创建的bean加到beanfactory里
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);
        }

    }
}
  1. populateBean(beanName, mbd, instanceWrapper) 填充属性
  2. initializeBean(beanName, exposedObject, mbd) 调用初始化方法
  3. 如果允许提前暴露bean 则通过getSingleton(beanName, false)提前获取bean
  4. earlySingletonReference 赋值给准备返回的 exposeObject
  5. 注册

3 createBeanInstance()

源码如下,发现逻辑好复杂啊,看官们莫怕,我们一步一步拆解

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 3.1 解析 bean,将 bean 类名解析为 class 引用
        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());
        }

        // 3.2 判断是否存在 Supplier 回调,若有则使用给定的回调方法初始化策略
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        // 3.3 若工厂方法不为空,则使用工厂方法初始化策略
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            // constructorArgumentLock 构造函数的常用锁
            synchronized (mbd.constructorArgumentLock) {
                // 3.4 可以利用构造函数解析,因为需要根据参数确认到底使用哪个构造函数,该过程比较消耗性能,所有采用缓存机制
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        // 若已解析,直接注入
        if (resolved) {
            // 3.5 自动注入,调用构造函数自动注入
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                // 3.6 使用默认构造函数构造
                return instantiateBean(beanName, mbd);
            }
        }

        // 3.7 通过检查已经注册的 SmartInstantiationAwareBeanPostProcessor 确定解析的构造函数
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            // 3.8 构造函数自动注入
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        //3.9使用默认构造函数注入
        return instantiateBean(beanName, mbd);
    }

1.resolveBeanClass(mbd, beanName) 解析bean 的classType,如果bean classType非 public 修饰或者其任一方法都不是 public,则抛出异常

protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch) throws CannotLoadBeanClassException {
    try {
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        } else {
            return System.getSecurityManager() != null ? (Class)AccessController.doPrivileged(() -> {
                return this.doResolveBeanClass(mbd, typesToMatch);
            }, this.getAccessControlContext()) : this.doResolveBeanClass(mbd, typesToMatch);
        }
    } catch (PrivilegedActionException var6) {
        ClassNotFoundException ex = (ClassNotFoundException)var6.getException();
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
    } catch (ClassNotFoundException var7) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), var7);
    } catch (LinkageError var8) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), var8);
    }
}

未完待续...