欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Ioc容器中的依赖注入-中篇 createBean方法

程序员文章站 2022-05-07 18:37:15
...

前面已经介绍了 getBean方法,我们已经知道了getBean方法是依赖注入的起点,之后就会调用createBean方法
简单的描述下:createBean方法中的一些作用,Bean会根据BeanDefinition定义的要求生成,具体的实现类就是在AbstractAutowireCapableBeanFactory类中实现了createBean方法,在CreateBean方法中不但生成了需要的Bean,还对Bean的初始化做了一些处理,例如对BeanDefinition中的init-method属性定义,对Bean的后置处理器等
首先来看下依赖注入的整体流程图:
Ioc容器中的依赖注入-中篇 createBean方法
下面主要的就是对createBean方法进行具体的源码分析:

//这个方法是创建了一个Object类
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Creating instance of bean '" + beanName + "'");
        }

        RootBeanDefinition mbdToUse = mbd;
      
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            //判断这个类是否可以被实例化,通过类加载器来完成,可以的话就执行实例化
            mbdToUse = new RootBeanDefinition(mbd);
            //然后就设置实例化的对象中去
            mbdToUse.setBeanClass(resolvedClass);
        }

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

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var10) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
        }

        try {
            //这里是创建Bean的地方
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Finished creating instance of bean '" + beanName + "'");
            }

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
        }
    }

接下来就是分析doCreateBean方法创建Bean对象的源码分析-也就是实际生成Bean的地方
doCreateBean()方法的分析

//记住这个抛出的异常都是BeanCreationException异常
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
      //其中的BeanWrapper对象使用封装创建的bean的对象
        BeanWrapper instanceWrapper = null;
       //判断是否为单例模式的对象。是的就根据Bean名字删除缓存中的已经存在的bean
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            //在这里就是根据BeanName,RootBeanDefinition,Object数组来创建
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

       //这里是对后置处理器执行加锁的操作
        synchronized(mbd.postProcessingLock) {
            //如果有后置处理器就是执行下面的代码
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }
                //设置后置处理器为true的状态
                mbd.postProcessed = true;
            }
        }
    
    //
    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
            
            //将beanName添加进去SingletonFactory工厂里面去
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

    //expose暴露的,无遮挡的对象
        Object exposedObject = bean;

        try {
            //populate平民的bean对象
            this.populateBean(beanName, mbd, instanceWrapper);
            //进行完初始化之后就返回
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    //这里进行了对BeanName的所有的依赖对象的代码分析
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    //定义一个LinkedHashsset集合来存储
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        //判断缓存中是否存在,如果不存在添加进入到集合中去
                        if (!this.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 {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

其中主要的两个方法就是:
createBeanInstance 生成bean对象的方法
populateBean 这个方法,后面会进行详细的分析

相关标签: 读书笔记