spring源码系列-Bean的创建流程

上一篇文章 spring源码系列-容器之XmlBeanFactory 中,我们以XmlBeanFactory为例,分析了spring 配置文件的解析,及容器的初始化流程。历经九九八十一难,终于拿到了BeanDefinition,并将之保存到beanDefinitionMap中,这些解析的数据毫无疑问是创建bean的基础,那么bean的创建究竟经历了什么非人的过程?这篇文章,我们将会一探究竟。本文可以分为以下几个板块

  1. 前言
  2. bean的创建
    2.1 转换对应的beanName
    2.2 从缓存中加载bean
    2.3 bean的实例化
    2.4 原型模式的依赖检查
    2.5 从parentBeanFactory加载配置
    2.6 转换rootBeanDefinition
    2.7 寻找依赖
    2.8 针对不同的scope进行bean的创建
    2.8.1 处理MethodOverrides
    2.8.2 实例化的前置处理
    2.8.3 根据不同的策略实例化bean
    2.8.4 暴露创建工厂
    2.8.5 属性填充
    2.8.6 初始化
    2.8.7 注册销毁相关方法
    2.9 类型转换
  3. 总结

1. 前言

在开始分析之前,我们先思考几个小问题。

  1. 程序设计的原则之一单一职责。那么如果程序职责划分不明确,多个bean之间存在循环依赖的情况,如ServiceA依赖ServiceB,ServiceB 又依赖ServieA。因为spring 创建bean的时候,会去初始化依赖,那么这种循环依赖,该如何处理呢?
  2. 我们都知道spring的bean是单例的。那么spring的bean 是如何实现单列的呢?是懒汉模式,饿汉模式,还是双重锁单列,还是枚举单列?
  3. 我们都知道spring关于bean的生命周期中提供了很多可扩展的点,如BeanPostProcessor,InitializingBean,init-method,destory-method等,这些关键扩展点是如何实现的,执行顺序是什么?
  4. spring bean创建的时候会存在依赖注入的情况,注解/配置文件。那么依赖注入是如何实现的呢?
    那么我们就带着这些问题,共同阅读一下spring的源码,看看spring背着我们,到底偷偷做了什么。

2. bean的创建

在开始bean创建流程分析之前,我们先回顾一下bean创建的基础用法。

        //步骤1:初始化BeanFactory
        BeanFactory beanFactory=new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        //步骤2:获取Bean
        Person person=(Person) beanFactory.getBean("um");

其中步骤1是我们上篇文章分析的重点,而步骤2究竟是怎么实现的呢?

Bean的创建.jpg

从流程图中可以看出来,主要分为以下步骤:
1. 转换beanName
2. 尝试从缓存或者提前暴露的BeanFactory中获取实例
3. bean的实例化(存在FactoryBean的情况)
4. 原型类型循环引用的检查
5. 尝试从父类工厂中实例化bean
6. 转换RootBeanDefinition,并合并父类属性
7. 查找并实例化依赖-depend on
8. 根据不同的scope做bean的创建
9. 类型转换

protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
        //1. 转换beanName
        final String beanName = transformedBeanName(name);
        Object bean;

        // 2. 尝试从缓存或者提前暴露的BeanFactory中获取实例
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //3. bean的实例化(存在FactoryBean的情况)
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            //4. 原型类型循环引用的检查
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 5. 尝试从父类工厂中实例化bean
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //6. 转换RootBeanDefinition,并合并父类属性
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 7. 查找并实例化依赖-depend on
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // 8. 根据不同的scope做bean的创建
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                // Explicitly remove instance from singleton cache: It might have been put there
                                // eagerly by the creation process, to allow for circular reference resolution.
                                // Also remove any beans that received a temporary reference to the bean.
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                beforePrototypeCreation(beanName);
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                finally {
                                    afterPrototypeCreation(beanName);
                                }
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // 9. 类型转换
        if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

其中步骤8是bean创建最核心的流程,接下来,我们来详细分析下整个流程,步骤8将是我们关注的核心部分。

2.1 转换对应的beanName

  1. 处理FactoryBean,比如beanName 为 &user,此时会将& 截取掉
  2. 根据beanName查找真正的Name。比如我们定义了一个bean,id="user",name="student",alias="teacher"。那么我们在getBean(name)时,name 传user,student,teacher 任何一个都可以得到我们定义的bean,切转换后的beanName是 user。
    /**
     * 如果以& 开头,则截取除&的剩余部分
     */
    protected String originalBeanName(String name) {
        String beanName = transformedBeanName(name);
        if (name.startsWith(FACTORY_BEAN_PREFIX)) {
            beanName = FACTORY_BEAN_PREFIX + beanName;
        }
        return beanName;
    }
    /**
     * beanName转换
     */
    public String canonicalName(String name) {
        String canonicalName = name;
        // Handle aliasing...
        String resolvedName;
        do {
            resolvedName = this.aliasMap.get(canonicalName);
            if (resolvedName != null) {
                canonicalName = resolvedName;
            }
        }
        while (resolvedName != null);
        return canonicalName;
    }

2.2 尝试从缓存或者提前暴露的BeanFactory中获取实例

1. 尝试从缓存(new ConcurrentHashMap<String, Object>(256))中加载bean。
2. 1中缓存不存在,且是单例bean的循环依赖,尝试从BeanFactory中加载bean,解决单列的循环依赖。

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }

单列在spring的同一个容器中只会被创建一次,后续再获取bean的时候,首先会尝试从缓存中加载。如果缓存中不存在,且是单列模式下的循环引用,则从提前暴露的BeanFactory中加载。如果加载不到,则会走创建流程。值得注意的是:spring 只会解决单列且非构造函数注入情况下的循环依赖,原型模式下会报错。

2.3 bean的实例化(存在FactoryBean的情况)

可能到这里大家有点疑问,在2.2 中我们已经尝试了从缓存中加载了bean,为什么还要在这里做bean的实例化呢?不是已经实例化了吗?其实如下
1. 当前bean非FactoryBean,直接返回
2. 当前bean为FactoryBean,则调用被覆盖的getObject()方法获取实例。
可以看到这里的处理只是针对FactoryBean

protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

        // Don't let calling code try to dereference the factory if the bean isn't a factory.
        if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
        }

        // Now we have the bean instance, which may be a normal bean or a FactoryBean.
        // If it's a FactoryBean, we use it to create a bean instance, unless the
        // caller actually wants a reference to the factory.
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }

        Object object = null;
        if (mbd == null) {
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // Return bean instance from factory.
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // Caches object obtained from FactoryBean if it is a singleton.
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }

2.4 原型类型循环引用的检查

  1. 缓存中未加载到bean,那么会检查是否存在原型(scope=prototype)下的循环依赖
  2. prototype模式下,spring是无法解决循环依赖的,因为prototype模式下bean 是无法共享的。如果A中有B的属性,B中又有A的属性,那么当依赖注入的时候,A还未创建完成时因为实例化依赖B而需要再次实例化A,造成循环依赖。
    3.singleton 模式下,spring 通过提前暴露beanFactory来解决循环依赖。singleton模式下,如果A中有B的属性,B中又有A的属性,当依赖注入时,A还未创建完成时因为实例化依赖B而需要再次实例化A,此时调用的提前暴露的单列工厂的实例化方法。获取的是同一个bean。
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
        Object curVal = this.prototypesCurrentlyInCreation.get();
        return (curVal != null &&
                (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
    }

注意:原型模式循环依赖的判断条件是,原型对象集合是否含有要创建的实例。

2.5 尝试从父类工厂中实例化bean

1. parentBeanFactory 不为空,且parentBeanFactory 包含要查找bean的定义。即通过beanName,能找到BeanDefinition
2. 满足条件1,则尝试从parentBeanFactory中加载bean

BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

注意:一般情况下parentBeanFactory都是不存在的。

2.6 转换RootBeanDefinition,并合并父类属性

1. 从缓存(容器初始化时解析配置文件得到并存入缓存)中获取GenericBeanDefinition,并将其转换为RootBeanDefinition。spring源码系列-容器之XmlBeanFactory
2. 如果parent不为空,则需要将parent的属性也合并进来。
好吧,终于轮到GenericBeanDefinition出场,并大显身手的时候了。

if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }

            if (mbd == null) {
                if (bd.getParentName() == null) {
                    // Use copy of given root bean definition.
                    if (bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                    }
                    else {
                        mbd = new RootBeanDefinition(bd);
                    }
                }

2.7 查找并实例化依赖-depend on

1. 查找依赖-dependOn(这里的依赖,指的不是我们常说的依赖注入属性。而是当前bean可能用到特定的bean,而这个特定的bean 要放在当前bean之前加载。)
2. 初始化依赖-dependOn

String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

2.8 根据不同的scope做bean的创建

到这里终于要见到bean创建的核心流程了(内心留下了悔恨的泪水⊙﹏⊙∥)。
bean的创建也是一个复杂的过程,spring会根据bean的scope属性的不同而做不同的处理,因为绝大多数场景我们的bean都是单列的,所以我们以Singleton为例,分析下bean的创建过程。
1. 尝试从缓存中加载
2. 如果缓存不存在,则将bean标记为正在创建
3. 调用ObjectFactory.getObject()方法创建bean
4. 移除正在创建状态
5. 删除各种创建时状态,并添加缓存

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "'beanName' must not be null");
        synchronized (this.singletonObjects) {
            //1.尝试从缓存中加载bean
            Object singletonObject = this.singletonObjects.get(beanName);
            //缓存中不存在,则走bean的创建流程
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                //2.创建的准备,将bean标记为创建中
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<Exception>();
                }
                try {
                    //3.通过调用传入的ObjectFactory.getObject()方法来创建bean
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    //4.移除bean的创建状态
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    //5.添加缓存
                    addSingleton(beanName, singletonObject);
                }
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }
    }

其中步骤3调用ObjectFactory.getObject()方法创建bean则是整个流程的核心,也是spring的核心。
给出其流程图:


getObject.jpg

可以看出整个流程还是比较复杂的。我们所熟知的aop,事物管理,依赖注入 等都是在这个过程中实现的。
ObjectFactory.getObject()大致包含如下流程:
1. 处理MethodOverrides
2. 实例化的前置处理
3. 根据不同的策略实例化bean,并包装成beanWapper
4. 提前暴露beanFactory
5. 属性填充
6. 调用初始化方法,即各种处理器
7. 注册销毁相关方法


2.8.1 处理MethodOverrides

MethodOverrides是什么呢?实际上在spring的配置文件中我们可以配置loopup-method和replace-method属性,在配置文件解析的时候会将其放入BeanDefinition的methodOverrides属性里。

2.8.2 实例化的前置处理

1. 遍历所有BeanPostProcessor,处理InstantiationAwareBeanPostProcessor类型
2. 调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)方法做前置处理
3. 调用InstantiationAwareBeanPostProcessor.applyBeanPostProcessorsAfterInitialization(bean, beanName)做后置处理

try {
            // InstantiationAwareBeanPostProcessor的前置和后置处理
            //扩展点一
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            //bean不为空,则终止后续bean创建的流程
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // 根据hasInstantiationAwareBeanPostProcessors属性判断,该属性是初始化ApplicationContexts的时候,提取并注册BeanPostProcessor时设置
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    //仅处理InstantiationAwareBeanPostProcessor类型的处理器
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    //bean不为空,则进行后置处理
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //仅处理InstantiationAwareBeanPostProcessor
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

说到这里,我们可能对InstantiationAwareBeanPostProcessor的执行逻辑有了一个认知,那么这个类到底有哪些熟知的实现呢?我们以Aop的核心类AbstractAutoProxyCreator为例,看下其postProcessBeforeInstantiation的实现

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            //基础类型 Pointcut。Advice。Advisor。AopInfrastructureBean 不需要代理
            //自定义是否需要代理
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        if (beanName != null) {
            //如果有配置TargetSource,则使用TargetSource定义的规则生成bean
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
                this.targetSourcedBeans.add(beanName);
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                //此步生成代理bean后,就会中断后续的bean创建流程
                return proxy;
            }
        }

        return null;
    }

2.8.3 根据不同的策略实例化bean,并包装成beanWapper

1. 根据参数解析调用不同的构造函数
2. 如果 1)能匹配对应的构造函数,2)或者注入方式为通过构造函数注入,3)或者构造函数参数不为空,4)或者创建bean参数不为空,则调用对应的构造函数实例化
3. 否则调用无参构造函数实例化

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        // Make sure bean class is actually resolved at this point.
        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());
        }

        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);
            }
        }

        // Need to determine the constructor...
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // No special handling: simply use no-arg constructor.
        return instantiateBean(beanName, mbd);
    }

2.8.4 暴露创建工厂

1. 判断是否提前暴露(单例&容许循环依赖&bean的状态为创建中)
2. 条件符合将ObjectFactory 添加进缓存(添加进缓存的同时,将当前创建中的bean 传入ObjectFactory)
还记得我们一开始的问题,spring是如何解决循环依赖的吗?这个步骤正是解决循环依赖的关键。

// Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        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);
                }
            });
        }
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                    if (exposedObject == null) {
                        return null;
                    }
                }
            }
        }
        return exposedObject;
    }

我们以A中有B,B中有A为例分析解决循环依赖的过程

  1. 执行A的创建过程
  2. 在创建A的时候将A的ObjectFacotry提前暴露(同时将当前A传入)
  3. 执行populateBean(beanName, mbd, instanceWapper),填充A的属性,发现未初始化的引用B,需要创建B
    3.1 执行创建B
    3.2 在创建B的时候将B的ObjectFactory提前暴露
    3.3 填充B的属性,发现需要注入A,执行创建A的流程
    3.4 执行创建A的时候先从提前暴露的ObjectFactory 里取A,执行步骤2里添加的ObjectFactory.getObject(),返回步骤2 传入的A
    3.5 在B中注入A,完成B的实例化
  4. 继续执行主流程A的创建,注入 3.5中的B
  5. 完成A的创建

2.8.5 属性填充

  1. 获取要注入的属性
  2. 将要注入的属性应用到当前bean中(未初始化时会先初始化)
    上面文章我们说解析配置文件生成BeanDefintion的过程中,会将要注入的属性以PropertyValues的形式存放,那么这个属性正是在属性注入的基础。
    关于属性注入,后续我们会结合注解如@Autowired.@Resource 做一个专门的介绍

2.8.6 初始化

当完成2.8.5 的时候,我们已经拿到一个bean的实例,并且这个bean的属性也已经做了填充。那么这里的初始化是什么含义呢?我们在配置bean的时候可以配置init-method,destory-method,以及可以使用各种处理器,做前置和后置处理。这些功能都是在这一步完成的,所以这里的初始化更多的是对bean进行增强及定制。
1. 激活Aware(调用 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware 的set 方法进行设置相应的属性)
2. 处理器的前置处理,BeanPostProcessor.postProcessBeforeInitialization(遍历所有注册的BeanPostProcessor)
3. 执行InitializingBean.afterPropertiesSet(只有当前bean 为InitializingBean类型时才会执行)
4. 执行定制化方法 init-method
5.处理器的后置处理,BeanPostProcessor.applyBeanPostProcessorsAfterInitialization(遍历所有注册的BeanPostProcessor)

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            //激活aware方法
            //BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //BeanPostProcessor前置处理
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //初始化方法 afterPropertiesSet,init-method
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //BeanPostProcessor后置处理
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {

        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isDebugEnabled()) {
                logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                        @Override
                        public Object run() throws Exception {
                            ((InitializingBean) bean).afterPropertiesSet();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

到此位置,我们完成了整个bean的初始化过程,我们所熟知的aop 也是在这个过程中通过BeanPostProcessor扩展来实现的,如AnnotationAwareAspectJAutoProxyCreator。关于Aop的实现,我们会在后续文章中详细介绍。

2.8.7 注册销毁相关方法

spring中除了可以定义初始化相关方法,还可以定义销毁相关方法,自定义销毁相关方法。
1. 配置 destory-method
2. 实现DisposableBean,并由DestructionAwareBeanPostProcessor统一处理。
值得注意的是,要触发销毁,要显示调用容器的destroySingletons或者其他销毁方法才能触发销毁操作。

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()) {
                // Register a DisposableBean implementation that performs all destruction
                // work for the given bean: DestructionAwareBeanPostProcessors,
                // DisposableBean interface, custom destroy method.
                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));
            }
        }
    }

2.9 类型的转换

到这里bean的创建基本上就结束来,但是有时候会存在,得到的类型和我们要求的类型requireType不一致的情况,这个时候就需要进行类型的转换。

        if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }

3 总结

到此,我们分析了spring 创建的过程,可以看到spring的创建过程还是比较复杂的。spring为我们提供了许多的扩展点,利用这些扩展点我们可以很优雅将自定义的处理逻辑融合到spring 容器中。篇幅限制,未对部分细节如属性填充进行深入分析,后续文章中我们会结合实际案例分析相关实现。

最后希望大家读了本篇文章都有自己的收获。我们下一篇文章见。。。。。

参考文章
Spring 源码深度解析-郝佳

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容