(一)Spring IoC源码-2.bean的加载-04创建bean

版权声明:本文版权归作者所有,欢迎转载。转载时请在文章明显位置给出作者名字(潘威威)及原文链接。请勿将本文用于任何商业用途。 https://blog.csdn.net/panweiwei1994/article/details/79868685

本文已收录于【Spring源码札记专栏】

关联文章:
(一)Spring IoC源码-2.bean的加载-01整体概览
(一)Spring IoC源码-2.bean的加载-02从缓存中获取单例bean
(一)Spring IoC源码-2.bean的加载-03从bean实例中获取目标对象
(一)Spring IoC源码-2.bean的加载-04创建bean

创建bean过程概述

创建bean是通过AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])完成的。

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

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

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

    try {
        //如果配置文件中配置了BeanPostProcessor,则返回一个代理对象。
        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 {
        //委托doCreateBean方法创建bean
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    catch (BeanCreationException ex) {
        // A previously detected exception with proper bean creation context already...
        throw ex;
    }
    catch (ImplicitlyAppearedSingletonException ex) {
        // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

可以看出,创建bean的功能是委托doCreateBean方法来完成的。在执行doCreateBean方法前,还处理了override属性和做了前置处理。下面看下doCreateBean方法的代码。

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

    BeanWrapper instanceWrapper = null;
    //如果是单例模式的Bean,先从缓存中获取并删除同名Bean
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    //如果没能从缓存中获取到bean,创建bean实例
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    //获取bean的类型
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    mbd.resolvedTargetType = beanType;

    if (beanType != null) {
        // MergedBeanDefinitionPostProcessor的应用
        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;
            }
        }
    }

    //是否需要提前曝光:是否是单例 & 是否允许循环依赖 & 当前 bean是否正在创建中
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        //依赖处理。为了避免循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory加入工厂
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        //属性注入。对bean进行填充,将各个属性值注入
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            //初始化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) {
            //已注册的单态模式Bean对象和正在实例化的Bean是同一个
            if (exposedObject == bean) {
                //当前实例化的Bean初始化完成
                exposedObject = earlySingletonReference;
            }
            //当发生循环引用时不允许新创建实例对象,并且当前Bean依赖其他Bean
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                 //获取当前Bean所依赖的其他Bean
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                //对依赖Bean进行检查,筛选出正在创建的bean
                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.");
                }
            }
        }
    }

    if (bean != null) {
        // 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. 清除缓存。如果是bean是单例bean,需要首先清除缓存。
  2. 创建bean实例。
  3. MergedBeanDefinitionPostProcessor的应用。bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析。
  4. 避免循环依赖。为了避免循环依赖,可以在 bean初始化完成前将创建实例的 ObjectFactory加入工厂。
  5. 属性注入。将所有属性填充至bean的实例中。
  6. 初始化bean。
  7. 循环依赖检查。Sping 中解决循环依赖只对单例有效,而对于prototype的bean,Spring 没有好的解决办法,唯一要做的就是抛出异常。在这个步骤里面会检测已经加载的 bean 是否已经出现了依赖循环,并判断是否需要抛出异常。
  8. 注册DisposableBean。
  9. 完成创建并返回。

创建bean实例

createBeanInstance(String, RootBeanDefinition, Object[])负责实例化bean。实例化方式有很多种,比如工厂方法和构造函数,具体使用哪种方式由BeanDefinition指定。

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<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }
    //使用工厂方法实例化
    if (mbd.getFactoryMethodName() != null)  {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same 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() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // 使用默认的构造函数实例化
    return instantiateBean(beanName, mbd);
}

避免循环依赖

参考(一)Spring IoC源码-2.bean的加载-02从缓存中获取单例bean(一)IoC源码-3.其他特性的实现原理-02循环依赖的解决

属性注入

前面已经介绍了如何实例化bean。在此基础上,需要对实例化的bean进行属性注入,即对bean的属性的处理(依赖关系的处理)。populateBean(String, RootBeanDefinition, BeanWrapper)负责这个任务。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    //获取BeanDefinition中的property值
    PropertyValues pvs = mbd.getPropertyValues();

    if (bw == null) {
        if (!pvs.isEmpty()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // Skip property population phase for null instance.
            return;
        }
    }

    // 给后置处理器InstantiationAwareBeanPostProcessors最后一次机会在设置属性前改变bean的状态。
    boolean continueWithPropertyPopulation = true;

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }
    //如果后置处理器发出停止属性填充的命令,则中断属性填充
    if (!continueWithPropertyPopulation) {
        return;
    }

    //对依赖注入处理,首先处理autowire自动装配的依赖注入
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        //根据Bean名称进行autowire自动装配处理
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        //根据Bean类型进行autowire自动装配处理 
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
    }

    //后处理器是否已经初始化
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    //是否需要依赖检查
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

    if (hasInstAwareBpps || needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        //如果后处理器已经初始化
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        //如果需要依赖检查
        if (needsDepCheck) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }
    //将属性注入到bean中
    applyPropertyValues(beanName, mbd, bw, pvs);
}

将属性注入步骤总结如下:

  1. 给后置处理器InstantiationAwareBeanPostProcessors最后一次机会在设置属性前改变bean的状态。
  2. 处理autowire自动装配的依赖注入
  3. 将属性注入到bean中

初始化

在对bean进行实例化、属性注入后,接下来的操作是对bean进行初始。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        //处理特殊的bean
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    //对Bean的后置处理器BeanPostProcessor的postProcessBeforeInitialization方法的调用
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    if (wrappedBean != null) {
        try {
            //调用bean的初始化方法,初始化方法通过inti-method属性指定。
            //如果bean实现了InitializingBean接口,那么bean的afterPropertiesSet()实现也会被调用。
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        //对Bean的后置处理器BeanPostProcessor的postProcessAfterInitialization方法的调用
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    }

    return wrappedBean;
}

将步骤总结如下:

  1. 处理特殊的bean(实现了Aware相关接口的bean)。
  2. 对Bean的后置处理器BeanPostProcessor的postProcessBeforeInitialization方法的调用。
  3. 调用bean的初始化方法,初始化方法通过inti-method属性指定。如果bean实现了InitializingBean接口,那么bean的afterPropertiesSet()实现也会被调用。
  4. 对Bean的后置处理器BeanPostProcessor的postProcessAfterInitialization方法的调用。

注册DisposableBean

Spring不但提供了初始化方法的扩展入口,也提供了销毁方法的扩展入口。对于销毁方法的扩展,除了我们熟知的destroy-method属性外,用户开可以注册后处理器DestructionAwareBeanPostProcessor。

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            registerDisposableBean(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
        else {
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}

bean的生命周期

了解了以上内容后,我们可将bean的生命周期总结如下:

  1. 实例化。Spring对Bean进行实例化(默认是单例)
  2. 属性注入。Spring将值和Bean的引用注入进Bean对应的属性中
  3. 初始化。
    1. 如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()方法。
    2. 如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanDactory(BeanFactory bf)方法并把BeanFactory容器实例作为参数传入。
    3. 如果Bean实现了ApplicationContextAwaer接口,Spring容器将调用setApplicationContext(ApplicationContext ctx)方法,把应用上下文作为参数传入。
    4. 如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessBeforeInitialization方法。
    5. 如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet方法,作用与在配置文件中对Bean使用init-method声明初始化的作用一样,都是在Bean的全部属性设置成功后执行的初始化方法。
    6. 如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessAfterInitialization方法。
  4. 注册DispostbleBean。
  5. 经过以上的工作后,Bean将一直驻留在应用上下文中给应用使用,直到应用上下文被销毁。
  6. Bean实例销毁前,如果Bean实现了DispostbleBean接口,Spring将调用它的destory方法。

End。

猜你喜欢

转载自blog.csdn.net/panweiwei1994/article/details/79868685