Spring如何实现bean的创建和实例化?

Spring框架最主要的东西就是IOC注入,那么它是如何将java类变成 bean 然后注入容器 又是如何将bean实例化的呢  

首先我们需要了解什么是BeanFactory ,BeanFactory 是一个接口 他有很多子接口,  简单的理解就是一个容器,用来管理bean.整一个流程

其中ApplicationContext我们都很熟悉,就是BeanFactory的一个子接口.

在启动阶段 系统通过扫描注解 读取XML等方式获取bean的属性信息,然后转化成BeanDefinition ,BeanDefinition可以理解为一个模板类  存放bean的方法字段等一系列信息  

然后通过BeanFactory 的实现类会把这些BeanDefinition 注册到容器中  本质就是放到一个ConcurrentHashMap中,在
需要实例化的时候拿出来。

下面这个方法registerBeanDefinition就是注册BeanDefinition到容器

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "Bean definition must not be null");
    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {
            ((AbstractBeanDefinition)beanDefinition).validate();
        } catch (BeanDefinitionValidationException var4) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var4);
        }
    }

    Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    if (oldBeanDefinition != null) {
        if (!this.allowBeanDefinitionOverriding) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': there's already [" + oldBeanDefinition + "] bound");
        }


        if (this.logger.isInfoEnabled()) {
            this.logger.info("Overriding bean definition for bean '" + beanName + "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
        }
    } else {
        this.beanDefinitionNames.add(beanName);
    }

    this.beanDefinitionMap.put(beanName, beanDefinition);
    this.removeSingleton(beanName);
}

 

此时Bean的定义其实已经存储在bean工厂里了 那么如何去实例化呢 .beanFactroy有个getBean方法  就是实例化的入口

我们拿其中一个beanFactroy的实现类举例

我们进入AbstractBeanFactory 看到

public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
    return this.doGetBean(name, requiredType, (Object[])null, false);
}

一直贴代码肯定看的头晕眼花  我这里就简单写了

AbstractBeanFactory 中我们发现一个getBean方法  这就是beanshih实例化的路口方法

------方法中又调用了doGetBean方法:

doGetBean方法中先会根据beanname判断缓存中有没有  因为bean创建后默认是单例的  会先放到缓存中 下次如果要用就可以免去重复创建了,这里会根据beandefintion中的信息判断是单例还是多例,单例会加入缓存 方便下次使用。

---doGetBean方法中又调用了createBean方法:

进入方法观察 ,createBean中通过resolveBeanClass解析bean的类型等操作   。

---createBean方法中调用了doCreateBean:

这里贴上一代码 解释一下:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
   //该BeanWrapper持有将要实例化的bean对象 
    BeanWrapper instanceWrapper = null;
    //如果是单例模式,则清除同名的bean对象
    if (mbd.isSingleton()) {
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }
     //实例化bean
    if (instanceWrapper == null) {
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }

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

    Object var7 = mbd.postProcessingLock;
    synchronized(mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                //MergedBeanDefinitionPostProcessor后处理器修改已合并的bean定义
                this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable var17) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
            }

            mbd.postProcessed = true;
        }
    }

    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if (earlySingletonExposure) {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
        }

        this.addSingletonFactory(beanName, () -> {
            return this.getEarlyBeanReference(beanName, mbd, bean);
        });
    }

    Object exposedObject = bean;
 
    try {
         //此时已完成bean的实例化 这里是给bean的属性赋值
        this.populateBean(beanName, mbd, instanceWrapper);
        //bean的初始化
        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)) {
                String[] dependentBeans = this.getDependentBeans(beanName);
                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 {
        //将bean注册一个DisposableBean 用于容器销毁是销毁该bean
        this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
        //返回bean的实例
        return exposedObject;
    } catch (BeanDefinitionValidationException var16) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
    }
}
 

至此spring成功完成了bean的创建和实例化,当然我这只是粗劣地讲解,其中的许多细节我们没有细究 ,比如initializeBean方法如何完成初始化 还有循环依赖的问题 。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值