Spring源码分析之createBean主流程分析

 2019-10-17 22:05  阅读(1713)
文章分类:Spring boot

我们知道,在调用getBean获取bean实例的实例,首先会从缓存中获取bean实例,如果没有获取到,就会去创建bean的时候。关于获取bean实例,可以参考Spring源码分析之getBean主流程分析,而本文将会对创建bean实例的主流程来做一个分析。而入口,当然是createBean(AbstractAutowireCapableBeanFactory)的方法。

下面来看源码:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) 
                throws BeanCreationException {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;
        //1:解析bean的类型
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        try {
        //2:处理 lookup-method 和 replace-method 配置,而Spring统称为override method
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            ........
        }

        try {
        //3:bean的后置处理器,如果有,这里会返回代理的实例。AOP的实现基础就是基于这里来实现的
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            ........
        }
        //来创建bean的实例
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }

其主流程逻辑也是比较的简单的:

  1. 对bean类型的解析
  2. 处理methodOverrides
  3. 处理bean实例的后置处理器。如果有,则返回一个代理的类。这里实际上是判断类有没有实现InstantiationAwareBeanPostProcessor接口。
  4. 创建实例bean并返回。

下面我们来看看doCreateBean中的逻辑:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {
        //bean实例包装类
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            //从缓存中清理相关中的包装类
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //创建bean的时候,这里创建bean的实例有三种方法
            //1:工厂方法创建
            //2:   利用构造方法的方式注入
            //3:   利用无参构造方法注入
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        //这里的bean应该是才被实例化的bean,还未被填充相关的属性
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        mbd.resolvedTargetType = beanType;

        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    .........
                }
                mbd.postProcessed = true;
            }
        }

        //判断是否是早期引用的bean,如果是,则允许其提前暴露引用
        //这里判断的逻辑主要有三个:
        //1:是否为单例:isSingleton
        //2:是否允许循环引用 :allowCircularReferences
        //3:是否是在创建中的bean:isSingletonCurrentlyInCreation
        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");
            }
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        Object exposedObject = bean;
        try {
            //填充bean的属性
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
            //初始化bean,过程如下:
            //1:判断是否实现了BeanNameAware,BeanClassLoaderAware以及
            //   BeanFactoryAware方法,如果有,则设置相关的属性
            //2: 调用bean初始化的前置操作
            //3: 执行初始化的方法。
            //  如果有initializingBean,则调用afterPropertiesSet
            //  如果有InitMethod,则调用初始方法
            //4: 调用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) {
            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<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        ......
                    }
                }
            }
        }
        //注册bean的销毁逻辑
        try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            ......
        }
        return exposedObject;
    }

实际创建bean实例的逻辑如下:

1:创建bean的实例(工厂方法,构造器注入的方式,简单初始化的方式)

2:是否允许其是否提前暴露引用,以便解决循环依赖的问题。

3:填充bean实例的属性

4:初始化操作(初始方法前操作,调用初始化方法,执行初始化后的方法)

5:解决循环依赖相关的问题。

6:注册bean的销毁逻辑。

至此,整个创建bean实例的主流程就分析完成了,下面将以一个简单的图来更加形象的展示其主流程调用逻辑。

20191017100421\_1.png
南瓜灯cc


来源:[]()

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Spring源码分析之createBean主流程分析

相关推荐