欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

深入理解Spring IOC(五) 、 创建bean实例

本篇我们讲上一篇中没有讲到的createBean方法,是在上一篇的代码块10中被调用这个方法,这个方法是位于AbstractAutowireCapableBeanFactory中:

                                        代码块1

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

    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }

    // 1.这个是确保mbd的beanClass属性是有值的
    resolveBeanClass(mbd, beanName);

    try {
        // 2. 验证以及准备mbd的方法覆盖属性
        mbd.prepareMethodOverrides();
    }catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 3. 这里主要是来针对代理的处理,如果是有代理之类需要替代真正bean的,就在这里返回结果了
        Object bean = resolveBeforeInstantiation(beanName, mbd);
        if (bean != null) {
            return bean;
        }
    }catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }

    // 4. 创建bean实例(这个才是真正创建bean的方法)
    Object beanInstance = doCreateBean(beanName, mbd, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}

1.1

                                        代码块2

protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
            throws CannotLoadBeanClassException {
    try {
        // 如果mbd已经有beanClass,则直接结束方法
        // 返回值是类的全类名,这里一般都有的
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        }
        // 这块还是和之前一样,if是特权执行,else是普通方式执行
        // 都是获取bean的全类名
        if (System.getSecurityManager() != null) {
            return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
                @Override
                public Class<?> run() throws Exception {
                    // 1.  真正解析bean的class
                    return doResolveBeanClass(mbd, typesToMatch);
                }
            }, getAccessControlContext());
        } else {
            return doResolveBeanClass(mbd, typesToMatch);
        }
    } catch (PrivilegedActionException pae) {
        ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
    } catch (ClassNotFoundException ex) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
    } catch (LinkageError err) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
    }
}

我们来看代码块2中的1处

                                       代码块3

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
    // 此时typesToMatch是个空数组,因此if跳过去
    if (!ObjectUtils.isEmpty(typesToMatch)) {
        ClassLoader tempClassLoader = getTempClassLoader();
        if (tempClassLoader != null) {
            if (tempClassLoader instanceof DecoratingClassLoader) {
                DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                for (Class<?> typeToMatch : typesToMatch) {
                    dcl.excludeClass(typeToMatch.getName());
                }
            }
            String className = mbd.getBeanClassName();
            return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
        }
    }
    // 返回bean的全类名,返回值为mbd中的beanClass属性,也就是bean的类型
    // 注意是全类名哈
    return mbd.resolveBeanClass(getBeanClassLoader());
}

1.2

这里的prepareMethodOverrides是在AbstractBeanDefinition中:

                                        代码块4

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    MethodOverrides methodOverrides = getMethodOverrides();

    //  methodOverrides存在并且不是空,则准备方法覆盖
    // 都是look-up(注解为@lookup)的方法和replace-method
    if (!methodOverrides.isEmpty()) {
        for (MethodOverride mo : methodOverrides.getOverrides()) {
            prepareMethodOverride(mo);
        }
    }
}

上面的代码是你的xml必须使用look-upmethod以及replace的时候才会执行到,我们来看上面最后调用的这个prepareMethodOverride方法:

                                        代码块5

protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    // 计算重载的方法的数量
    int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    // 0就直接抛出异常
    if (count == 0) {
        throw new BeanDefinitionValidationException(
                "Invalid method override: no method with name '" + mo.getMethodName() +
                "' on class [" + getBeanClassName() + "]");
    // 1的话设置这个属性为true,这个属性的作用是避免掉重载的检查
    // 可以在运行的时候提高性能
    } else if (count == 1) {
        // Mark override as not overloaded, to avoid the overhead of arg type checking.
        mo.setOverloaded(false);
    }
}

1.3

这里主要是生成各种代理的,比如说当你使用Dubbo中的@Reference注解注入一个服务对象的时候,这时候就是走的这里,我们来看看它的代码:

                                       代码块6

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    // 如果需要提前执行InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation方法
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // mbd有正确的class属性 && mbd不是合成的 && 存在InstantiationAwareBeanPostProcessor(这是个特殊的BeanPostProcessor)
        if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            // 1.执行postProcessBeforeInstantiation方法
            bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
            // 如果在这里返回了result,则执行所有的BeanPostProcessor的后置处理方法
            // 执行完了就代表一个完整的bean已经创建好
            if (bean != null) {
                bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

我们可以看出来,这块主要是来执行InstantiationAwareBeanPostProcessor的,为什么要在代码块1.3中这里调用呢?因为要给代理类一个机会替换掉原来的对象的,因为下一步就要在代码块1.4处都要调用doCreateBean创建真正的bean实例了。然后我们来看看代码块6中的1处,其实这里便是对应着执行InstantiationAwareBeanPostProcessor

                                       代码块7

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
            throws BeansException {
    // 遍历BeanPostProcessor
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        // 如果BeanPostProcessor 是个 InstantiationAwareBeanPostProcessor
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            // 强制转型
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

1.4

终于到这个doCreateBean方法了,这里才是真正创建bean的方法,也是包含逻辑最多的方法,我们不虚它,就是干,但是干之前,因为这个方法太过于复杂的原因,我先给你列个提纲,从宏观上告诉你这个方法都做了什么事情,再给你看源码,这样你就不至于很懵逼

这个doCreateBean方法,做了这些事情:1. 从工厂方法或者构造方法中二选一创建对象(取决于你的配置,这里包含的逻辑也最多,涉及到了构造方法的选择) 2. 接着是循环依赖的处理,主要是通过提前曝光的方式来处理 3. 进行属性的填充以及初始化操作,初始化中包含着bean的前置以及后置处理。

接着,我们来看看具体的代码:

                                       代码块8

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
    // BeanWrapper是bean的包装类
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 从正在创建的factoryBean的缓存中移除(准确说其实是去拿,同时移除)
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 1. 如果到这里是null,则去创建一个包含着bean实例的instanceWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

    // 使用MergedBeanDefinitionPostProcessor修改RootBeanDefinition
    // 主要是处理@Autowired 、 @inject 、@value 标着的方法和属性
    // 从这里往后,spring 才知道是哪个方法或者是属性有这个注解
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            mbd.postProcessed = true;
        }
    }

    // earlySingletonExposure是判断是否要提前曝光这个半成品的实例的,注意哈:现在的bean只是个半成品
    // 因为还没有进行属性填充,以及执行初始化方法等操作
    // mbd是单例 && 允许循环引用(默认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");
        }
        // 提前曝光这个beanName对应的ObjectFactory,用来解决循环引用
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                // 2.使用SmartInstantiationAwareBeanPostProcessor返回早期bean的半成品时的引用
                // 如果没有SmartInstantiationAwareBeanPostProcessor,则直接返回bean
                // 这里返回的最终是bean本身
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }

    // 初始化
    Object exposedObject = bean;
    try {
        // 3. 对bean进行属性填充
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // 4. 初始化操作
            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);
        }
    }

    // 如果需要提前曝光半成品bean
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                // 由于经过init之后的操作,earlySingletonReference和exposedObject可能不是一个实例,
                // 这里需要让他们指向一个实例,
                exposedObject = earlySingletonReference;
            // 不允许在循环依赖情况下注入原始bean && 当前bean被其他bean依赖
            }else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                // 拿到当前bean依赖所有bean的数组
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    // 移除这些bean,因为这些bean依赖的bean是被增强过的bean
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        // 移除失败的添加到actualDependentBeans
                        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,
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

这个doCreateBean方法,是整个spring 创建bean流程核心中的核心,当然难度也比较高,这部分代码是需要反复读的,最好你看我文章的同时还能去源码中跟一跟。这里面难度最大的方法也是这个第1处的代码(本篇也只讲这个方法,剩下的下一篇讲),这个代码创建了一个”不完整”的bean,为什么是不完整的呢?因为此时创建出来的bean还没有被进行属性填充,也就是被@Autowired以及@Resource标记的属性都还没有被注入。我们一起来看看这个方法:

                                    代码块9

// 使用不同的策略创建bean 实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
    // 拿到mbd的全类名,上一篇已经说过resolveBeanClass方法
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // beanClass不为null && beanClass是不是公共类(public修饰) && beanClass不允许访问非public的构造方法
    // 上述条件都满足就抛异常,因为都满足的话就没有构造方法可以调用了
    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());
    }

    // 如果存在factory-method,则使用factory-method创建BeanWrapper
    if (mbd.getFactoryMethodName() != null)  {
        // 1. 根据工厂方法来创建包含着bean实例的BeanWrapper实例
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // resolved表示构造方法或者工厂方法已经被解析过,autowireNecessary代表是否要解析构造方法参数
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            // resolvedConstructorOrFactoryMethod不为空,说明已经解析过,resolved标为true
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                // constructorArgumentsResolved如果是true,那autowireNecessary肯定是true
                // constructorArgumentsResolved源码注释的意思是构造方法参数是否已经被解析过
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    // 如果已经解析过
    if (resolved) {
        // 并且是需要解析构造方法参数
        if (autowireNecessary) {
            // 2. 能走到这里的前提是你的bean是个可以被多次解析的bean,也就是prototype,
            // 事实上也只有prototype并且是个构造方法注入的resolved和autowireNecessary才都会是true
            // 原因是singleton的会被缓存,再次getbean()的话根本都走不到这里来
            return autowireConstructor(beanName, mbd, null, null);
        }else {
            // 3.使用无参数的构造方法注入
            return instantiateBean(beanName, mbd);
        }
    }

    // 去拿候选的构造方法,
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 候选构造方法不是空 || 构造方法注入的方式 || mdb中有构造方法的参数值 || 参数不为空
    // 详细解释下这四个条件:(1)候选构造方法不是空是当注解情况下有@Autowired或@inject标着的构造器或者是你的类只有一个有参数构造
    //  或者你自己有实现了SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法
    // (2)是构造方法注入,(3)或者所需要的构造方法是有参的构造方法(因为某些时候我们的类只定义了一个有参构造),在或者就是
    // (4)传过来的参数不是null
    if (ctors != null ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
        // 执行构造方法注入(和2处是一个方法,只是参数不一样)
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // 使用无参数的构造方法注入
    return instantiateBean(beanName, mbd);
}

9.1

                                    代码块10

protected BeanWrapper instantiateUsingFactoryMethod(
            String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {

    return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

我们可以看到,这里只是直接调用了ConstructorResolver中的instantiateUsingFactoryMethod,这个方法是个非常长的同时也是个比较复杂的方法,我们直接来到ConstructorResolver中来看这个方法:

                                    代码块11

public BeanWrapper instantiateUsingFactoryMethod(
            final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {

    // new 一个bw, bw也是方法的结果
    BeanWrapperImpl bw = new BeanWrapperImpl();
    // 对bw进行起码的初始化,这句可以先跳过,你只要知道是个起码的初始化即可
    this.beanFactory.initBeanWrapper(bw);

    Object factoryBean;
    Class<?> factoryClass;
    boolean isStatic;

    // 拿到factoryBean的Name,xml中对应factory-bean属性
    String factoryBeanName = mbd.getFactoryBeanName();
    if (factoryBeanName != null) {
        // 如果factoryBeanName 和 目标bean的名称是一样的,则直接抛异常
        // 这个是指xml中bean标签的factory-bean和id属性值不能一样
        if (factoryBeanName.equals(beanName)) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                    "factory-bean reference points back to the same bean definition");
        }
        // 拿到factoryBeanName对应的bean,即beanName对应bean的factory类
        factoryBean = this.beanFactory.getBean(factoryBeanName);
        // 是null抛异常,因为根本没有这个factoryBean或者其创建出来的对象
        if (factoryBean == null) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null");
        }
        factoryClass = factoryBean.getClass();
        isStatic = false;
    }else {
        // 这个else代码块是静态工厂的处理,静态工厂不会在xml中指定factory-bean
        // 不知道类是哪个的话则抛异常
        if (!mbd.hasBeanClass()) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                    "bean definition declares neither a bean class nor a factory-bean reference");
        }
        factoryBean = null;
        factoryClass = mbd.getBeanClass();
        isStatic = true;
    }

    // 最终要用的方法
    Method factoryMethodToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    // 最终要用的方法的参数
    Object[] argsToUse = null;

    // 如果本方法传入的参数不是空则使用的是方法传入的参数
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }else {
    // 这个else 代码块主要是在拿已经解析并使用过的方法和方法参数的缓存
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
          // 注意哈,这里便体现出了RootBeanDefiniti缓存的作用了
            // 拿解析过的构造方法或是工厂方法
            factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
            // 已解析过的不为空 && mbd构造方法参数也是有的
            if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
                // 设置argsToUse为mbd解析过的构造方法的参数的缓存
                argsToUse = mbd.resolvedConstructorArguments;
                // 这个是候选的用来解析的
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        // 1. 解析要使用的参数为需要的类型
        if (argsToResolve != null) {
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
        }
    }

    if (factoryMethodToUse == null || argsToUse == null) {
        // 这段代码主要是在找哪个方法是静态工厂方法
        factoryClass = ClassUtils.getUserClass(factoryClass);
        // 拿到factoryClass的所有方法
        Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
        List<Method> candidateSet = new ArrayList<Method>();
        for (Method candidate : rawCandidates) {
            // 是静态方法 && 名字和mbd的工厂方法一样
            // 因为即使是静态并且名字是同一个,也存在可能有个多个重载的情况
            // 所以需要存到candidateSet进行进一步的筛选
            if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
                candidateSet.add(candidate);
            }
        }
        // candidateSet转为数组并排序
        Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);
        // 给方法排序,public排在非public之前,如果都是public,则参数多的排在前
        AutowireUtils.sortFactoryMethods(candidates);

        // 解析过的参数
        ConstructorArgumentValues resolvedValues = null;
        // 是否为构造器注入,这里一般都是false
        boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
        // 最小的权重,指的是参数类型不相同的权重,越小则说明越匹配
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Method> ambiguousFactoryMethods = null;

        // 最少需要的参数个数
        int minNrOfArgs;
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        }else {
            // 拿到beanDefinition中解析到的xml中定义的构造方法参数
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
            // 2.解析参数,并返回参数个数(解析体现在需要把“1”这样的string转化为了int)
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        List<Exception> causes = null;

        // 通过各种方式确定最终要使用的工厂方法是哪个,以及其中的参数
        // 遍历candidates
        for (int i = 0; i < candidates.length; i++) {
            // 拿到对应的方法作为候选方法和它的参数
            Method candidate = candidates[i];
            Class<?>[] paramTypes = candidate.getParameterTypes();
            // 如果这个方法的参数大于等于最小需要的参数
            if (paramTypes.length >= minNrOfArgs) {
                ArgumentsHolder argsHolder;

                if (resolvedValues != null) {
                    // Resolved constructor arguments: type conversion and/or autowiring necessary.
                    try {
                        // 参数名数组
                        String[] paramNames = null;
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            paramNames = pnd.getParameterNames(candidate);
                        }
                        // 3.解析参数
                        argsHolder = createArgumentArray(
                                beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
                    }catch (UnsatisfiedDependencyException ex) {
                        if (this.beanFactory.logger.isTraceEnabled()) {
                            this.beanFactory.logger.trace("Ignoring factory method [" + candidate +
                                    "] of bean '" + beanName + "': " + ex);
                        }
                        // i为最后一个,&& argsHolderToUse为null (还没找到合适的参数)
                        if (i == candidates.length - 1 && argsHolderToUse == null) {
                            // 如果有异常,此时也就该抛异常了
                            if (causes != null) {
                                for (Exception cause : causes) {
                                    this.beanFactory.onSuppressedException(cause);
                                }
                            }
                            throw ex;
                        }else {
                            // 如果有异常,就记录下来
                            if (causes == null) {
                                causes = new LinkedList<Exception>();
                            }
                            causes.add(ex);
                            continue;
                        }
                    }
                }else {
                    if (paramTypes.length != explicitArgs.length) {
                        continue;
                    }
                    argsHolder = new ArgumentsHolder(explicitArgs);
                }

                // 这个就是开始AbstractBeanDefinition中lenientConstructorResolution
                // 那个属性影响到的地方,具体体现在:如果是true,代表只要你的值转换过的类型可以和需要的类型
                // 能匹配上,就是你这个方法了。比如说:getInstance(Integer age),此时xml定义了age为18的参数,而由于xml中定义的参数都会被解析
                // 成String,因此需要转化,如果lenientConstructorResolution为true,则这里就可以匹配上这个方法
                // 因为18可以被转为Integer,如果是false,就不能匹配上这个方法了
                int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                        argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                // 根据权重选出最合适的方法和参数,权重小则说明越合适
                // minTypeDiffWeight的值此时是Integer.MAX_VALUE
                if (typeDiffWeight < minTypeDiffWeight) {
                    factoryMethodToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousFactoryMethods = null;
                // factoryMethodToUse不为null && 类型差异权重相同 && 不是宽松构造函数解析模式 && 候选方法的参数类型
                // 和factoryMethodToUse的长度相同 && 候选方法数组和factoryMethodToUse的参数类型不一样
                // 注意哈:typeDiffWeight 是不可能比 minTypeDiffWeight 大的,具体原因可以去计算typeDiffWeight
                // 的方法里看
                }else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
                        !mbd.isLenientConstructorResolution() &&
                        paramTypes.length == factoryMethodToUse.getParameterTypes().length &&
                        !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
                    // 添加到ambiguousFactoryMethods用作后续的抛异常用
                    if (ambiguousFactoryMethods == null) {
                        ambiguousFactoryMethods = new LinkedHashSet<Method>();
                        ambiguousFactoryMethods.add(factoryMethodToUse);
                    }
                    ambiguousFactoryMethods.add(candidate);
                }
            }
        }

        // 如果此时factoryMethodToUse还是null,则抛异常
        if (factoryMethodToUse == null) {
            List<String> argTypes = new ArrayList<String>(minNrOfArgs);
            if (explicitArgs != null) {
                for (Object arg : explicitArgs) {
                    argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
                }
            }else {
                Set<ValueHolder> valueHolders = new LinkedHashSet<ValueHolder>(resolvedValues.getArgumentCount());
                valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
                valueHolders.addAll(resolvedValues.getGenericArgumentValues());
                for (ValueHolder value : valueHolders) {
                    String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
                            (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
                    argTypes.add(argType);
                }
            }
            String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "No matching factory method found: " +
                    (mbd.getFactoryBeanName() != null ?
                        "factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
                    "factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
                    "Check that a method with the specified name " +
                    (minNrOfArgs > 0 ? "and arguments " : "") +
                    "exists and that it is " +
                    (isStatic ? "static" : "non-static") + ".");
        // 如果factoryMethodToUse返回值类型是void,则抛异常
        }else if (void.class.equals(factoryMethodToUse.getReturnType())) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Invalid factory method '" + mbd.getFactoryMethodName() +
                    "': needs to have a non-void return type!");
        // 如果ambiguousFactoryMethods不是null,则抛异常
        }else if (ambiguousFactoryMethods != null) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous factory method matches found in bean '" + beanName + "' " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                    ambiguousFactoryMethods);
        }

        // 将解析出来的参数和方法存到mbd的缓存中
        // 应该还知道mbd是个啥玩意吧?不知道的话赶紧回去看一看
        if (explicitArgs == null && argsHolderToUse != null) {
            argsHolderToUse.storeCache(mbd, factoryMethodToUse);
        }
    }

    // 到这块已经找到了要用的方法,以及要用的参数,可以去根据方法去创建对象了
    try {
        Object beanInstance;
        // 应用特权创建或者是普通创建
        if (System.getSecurityManager() != null) {
            final Object fb = factoryBean;
            final Method factoryMethod = factoryMethodToUse;
            final Object[] args = argsToUse;
            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    // 这里本质上还是在用反射调用
                    return beanFactory.getInstantiationStrategy().instantiate(
                            mbd, beanName, beanFactory, fb, factoryMethod, args);
                }
            }, beanFactory.getAccessControlContext());
        }else {
            beanInstance = beanFactory.getInstantiationStrategy().instantiate(
                    mbd, beanName, beanFactory, factoryBean, factoryMethodToUse, argsToUse);
        }

        if (beanInstance == null) {
            return null;
        }
        bw.setWrappedInstance(beanInstance);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

确实是个无比长的方法,所以我都是尽可能的是在代码内做解释,不用让你在方法这么长的情况下还得上下切屏幕,即使这样子,这也依然不那么简单,很多人也是被这个代码劝退的,看我文章的读者,你如果看到这里了,我觉得你还是有必要坚持一下的,因为已经到这样的地方了,这个过了,剩下的就都不难了。

11.1

这里主要是对参数的解析转换,即把给定的参数转化成正确的类型

                                    代码块12

private Object[] resolvePreparedArguments(
            String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {

    // 如果methodOrCtor是Method或者Constructor的实例,则拿到它的参数
    Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
            ((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
    // 类型转换器
    TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
            this.beanFactory.getCustomTypeConverter() : bw);
    // 值转换器
    BeanDefinitionValueResolver valueResolver =
            new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
    // 本方法的result
    Object[] resolvedArgs = new Object[argsToResolve.length];
    for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
        // 这里在做的事情主要就是对值类型的一个转换
        Object argValue = argsToResolve[argIndex];
        MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, argIndex);
        GenericTypeResolver.resolveParameterType(methodParam, methodOrCtor.getDeclaringClass());
        if (argValue instanceof AutowiredArgumentMarker) {
            argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
        }else if (argValue instanceof BeanMetadataElement) {
            argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
        }else if (argValue instanceof String) {
            argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
        }
        // 从这里能看出来,做的事情其实就是把“1”这样的变成了1,
        // 即把参数转化成真正需要的类型
        Class<?> paramType = paramTypes[argIndex];
        try {
            resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam);
        }
        catch (TypeMismatchException ex) {
            String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
            throw new UnsatisfiedDependencyException(
                    mbd.getResourceDescription(), beanName, argIndex, paramType,
                    "Could not convert " + methodType + " argument value of type [" +
                    ObjectUtils.nullSafeClassName(argValue) +
                    "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
        }
    }
    return resolvedArgs;
}

11.2

这里也是解析参数,但是这里是在解析xml中给定的参数,并返回所需要参数的最小个数,在这里,还有可能去寻找所依赖的bean

                                    代码块13

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
            ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

    // 类型转换器和值解析器
    TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
            this.beanFactory.getCustomTypeConverter() : bw);
    BeanDefinitionValueResolver valueResolver =
            new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);

    int minNrOfArgs = cargs.getArgumentCount();
    // 这里是那种标签里带着index配置的的参数,如果没有配这个index
    // 那将不会走这个循环
    for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
        int index = entry.getKey();
        // index不能小于0
        if (index < 0) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Invalid constructor argument index: " + index);
        }
        // index大于上面的最少需要参数个数,则最小的参数个数需要+1
        if (index > minNrOfArgs) {
            minNrOfArgs = index + 1;
        }
        // 拿到对应的value
        ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
        // 进行转化
        if (valueHolder.isConverted()) {
            // 如果以及转化过,则直接添加到resolvedValues中
            resolvedValues.addIndexedArgumentValue(index, valueHolder);
        }else {
            Object resolvedValue =
                    valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
            ConstructorArgumentValues.ValueHolder resolvedValueHolder =
                    new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
            resolvedValueHolder.setSource(valueHolder);
            // 将转化过的值添加到resolvedValues中
            resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
        }
    }
    // 这里是那种标签里带着index配置的的参数
    for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
        // 进行转化,逻辑和上面相同,只不过添加到了resolvedValues中
        // 的genericArgumentValue中
        if (valueHolder.isConverted()) {
            resolvedValues.addGenericArgumentValue(valueHolder);
        }else {
            Object resolvedValue =
                    valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
            ConstructorArgumentValues.ValueHolder resolvedValueHolder =
                    new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
            resolvedValueHolder.setSource(valueHolder);
            resolvedValues.addGenericArgumentValue(resolvedValueHolder);
        }
    }
    // 返回所需要的参数的个数
    return minNrOfArgs;
}

11.3

                                   代码块14

    // 创建工厂方法或者是构造方法的参数
    private ArgumentsHolder createArgumentArray(
            String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues,
            BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Object methodOrCtor,
            boolean autowiring) throws UnsatisfiedDependencyException {
    // 判断方法类型
    String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
    // 获取类型转换器
    TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
            this.beanFactory.getCustomTypeConverter() : bw);
    // args是本方法return的结果
    ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
    // usedValueHolders这个是已经解析出来的,用作过滤用
    Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
            new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length);
    Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
    // 遍历参数类型数组
    for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
        Class<?> paramType = paramTypes[paramIndex];
        String paramName = (paramNames != null ? paramNames[paramIndex] : null);
        // 根据下标去拿构造方法的参数
        ConstructorArgumentValues.ValueHolder valueHolder =
                resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
        // 如果没有找到需要的参数,并且不允许自动装配,则去尝试使用下一个无类型参数
        // 注:无类型参数的名称和类型必须是匹配的
        if (valueHolder == null && !autowiring) {
            valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
        }
        if (valueHolder != null) {
            // 此时已经找到一个“说不定能用”的参数
            usedValueHolders.add(valueHolder);
            // 拿到这个参数的值
            Object originalValue = valueHolder.getValue();
            Object convertedValue;
            // 如果参数类型已经被转化过则直接使用(其实就是加到args对应的位置)
            if (valueHolder.isConverted()) {
                convertedValue = valueHolder.getConvertedValue();
                args.preparedArguments[paramIndex] = convertedValue;
            }else {
                // 进行参数的类型转换
                ConstructorArgumentValues.ValueHolder sourceHolder =
                        (ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
                Object sourceValue = sourceHolder.getValue();
                try {
                    // 进行转换
                    convertedValue = converter.convertIfNecessary(originalValue, paramType,
                            MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex));
                    args.resolveNecessary = true;
                    // 将转换后的参数添加到args对应位置
                    args.preparedArguments[paramIndex] = sourceValue;
                }catch (TypeMismatchException ex) {
                    // 转换失败抛出异常
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, paramIndex, paramType,
                            "Could not convert " + methodType + " argument value of type [" +
                            ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
                            "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
                }
            }
            args.arguments[paramIndex] = convertedValue;
            args.rawArguments[paramIndex] = originalValue;
        }else {
            // 找不到明确的参数,并且不允许自动装配,则抛出异常
            if (!autowiring) {
                throw new UnsatisfiedDependencyException(
                        mbd.getResourceDescription(), beanName, paramIndex, paramType,
                        "Ambiguous " + methodType + " argument types - " +
                        "did you specify the correct bean references as " + methodType + " arguments?");
            }
            // 上面的是处理xml的,这里的是注解的,指的是@Autowired标在构造方法上面,需要处理参数的bean
            try {
                MethodParameter param = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
                Object autowiredArgument = resolveAutowiredArgument(param, beanName, autowiredBeanNames, converter);
                args.rawArguments[paramIndex] = autowiredArgument;
                args.arguments[paramIndex] = autowiredArgument;
                args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
                args.resolveNecessary = true;
            }catch (BeansException ex) {
                throw new UnsatisfiedDependencyException(
                        mbd.getResourceDescription(), beanName, paramIndex, paramType, ex);
            }
        }
    }

    for (String autowiredBeanName : autowiredBeanNames) {
        // 注册依赖关系
        this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
        if (this.beanFactory.logger.isDebugEnabled()) {
            this.beanFactory.logger.debug("Autowiring by type from bean name '" + beanName +
                    "' via " + methodType + " to bean named '" + autowiredBeanName + "'");
        }
    }

    return args;
}

代码块11的便说完了,我不知道有多少人能看到这里,说实话,写到这里,作者我自己也是崩溃的,我崩溃的地方不是我觉得它有多么的难,而是我实在没办法把这个方法搞得像大白话一样让你一下子能看懂,看这种源码,最崩溃的就是明明一个方法已经非常的长了,但是人家还一个套一个,你看完了里面套的一个巨长无比的方法之后回到原来的方法发现只前进了一行,然后很多人就被劝退了。其实我为了你看着容易,代码块11里有的方法我没有列出来,但是我的github上面的源码是有注释的,你按着我的引导对着源码看一遍,然后自己再一遍一遍的跟,会更容易一些。坚持真的很不容易,所以能到这里的人,作为作者,为你们点个赞,让我们一起加油。

说了一点点自己的感触哈,代码块9.1这个调用工厂方法创建bean已经完了,然后是9.2,9.2调用的代码和9.1的一样长,但是套路几乎是一样的,所以要是你真的看懂了上面的,下面的这个也就很容易了。

9.2

                                   代码块15

// 使用构造方法创建bean
public BeanWrapper autowireConstructor(
            final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
        // 创建并初始化BeanWrapper
    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

    // constructorToUse是要去使用的构造方法,argsHolderToUse是要用的构造方法的参数
    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    // 如果explicitArgs不为null,那最终要用的参数就为explicitArgs
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }else {
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            // 先尝试从mbd的缓存拿解析过的构造方法和其对应的参数
            // 注意哈,这块为什么会和之前那个根据工厂方法创建bean用的是一个mbd的变量做缓存的原因是:
            // 一个对象同时只能使用构造方法和工厂方法中的一个去创建(不理解这里的可以多看几遍源码)
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            // 构造方法不为空 && 并且构造函数的参数解析过
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // 缓存中拿已经解析出来的参数
                argsToUse = mbd.resolvedConstructorArguments;
                // 如果已经解析的为空,则去拿候选解析的
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        // 如果argsToResolve不为null,把参数解析为正确的类型,上面已讲过这个方法
        if (argsToResolve != null) {
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
        }
    }

    // 如果上面没有从缓存中拿到,则尝试去解析一个最合适的构造方法
    if (constructorToUse == null) {
        boolean autowiring = (chosenCtors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;

        // 构造方法参数个数
        int minNrOfArgs;
        // 如果给定的参数数组不是null,则使用给定的参数数组的长度
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        }else {
            // 这里的cargs其实就是我们xml定义的constructor-arg的东西
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        // 如果这时候方法参数里的构造方法数组是空的,那么
        // 就去拿beanClass的构造方法
        Constructor<?>[] candidates = chosenCtors;
        if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
                // 如果允许访问非公共构造方法,就拿所有构造方法
                // 否则只拿公共的
                candidates = (mbd.isNonPublicAccessAllowed() ?
                        beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                                "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
            }
        }

        // 给构造方法排序,public排在非public之前,如果都是public,则参数多的排在前
        AutowireUtils.sortConstructors(candidates);
        // 这块权重的这个套路和之前的是一样的
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        List<Exception> causes = null;

        for (int i = 0; i < candidates.length; i++) {
            // 对应下标的构造方法和其参数
            Constructor<?> candidate = candidates[i];
            Class<?>[] paramTypes = candidate.getParameterTypes();
            // 要用的构造方法不为空 && 其参数的长度大于现在这个下标的构造方法参数长度
            if (constructorToUse != null && argsToUse.length > paramTypes.length) {
                // 跳出循环不再查找,因为对于排序过后的数组来说,现在的constructorToUse已经是最合适的了
                break;
            }
            // 如果这个下标的构造方法的参数小于我们所需要的参数个数,则直接跳过这个构造方法
            if (paramTypes.length < minNrOfArgs) {
                continue;
            }

            ArgumentsHolder argsHolder;
            if (resolvedValues != null) {
                try {
                    // 这块是去拿本下标构造方法参数的真正的名字
                    String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
                    if (paramNames == null) {
                        // 如果paramNames还是null则用参数名解析器来解析参数
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                    // 去拿最终使用的构造方法的参数,之前讲工厂方法创建对象的时候已说过
                    argsHolder = createArgumentArray(
                            beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
                }catch (UnsatisfiedDependencyException ex) {
                    if (this.beanFactory.logger.isTraceEnabled()) {
                        this.beanFactory.logger.trace(
                                "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                    }
                    // 这个是指到candidates最后一个都还没找到可以用的构造方法,则抛出异常
                    if (i == candidates.length - 1 && constructorToUse == null) {
                        if (causes != null) {
                            for (Exception cause : causes) {
                                this.beanFactory.onSuppressedException(cause);
                            }
                        }
                        throw ex;
                    // 否则在这里吃掉异常,继续找下一个
                    }else {
                        // Swallow and try next constructor.
                        if (causes == null) {
                            causes = new LinkedList<Exception>();
                        }
                        causes.add(ex);
                        continue;
                    }
                }
            }else {
                // 参数的长度都不相同,肯定不是一个方法,则直接跳过
                if (paramTypes.length != explicitArgs.length) {
                    continue;
                }
                argsHolder = new ArgumentsHolder(explicitArgs);
            }

            // 权重,这里这个参数的意义和之前工厂方法创建对象的意义是一样的,
            // 不明白的可以翻上去看看
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                    argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // 根据权重选出最合适的方法和参数,权重小则说明越合适
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            // 记录下来用作抛异常
            }else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }

        // 没找到构造方法,则抛出异常
        if (constructorToUse == null) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Could not resolve matching constructor " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
        }else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous constructor matches found in bean '" + beanName + "' " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                    ambiguousConstructors);
        }

        if (explicitArgs == null) {
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    try {
        Object beanInstance;
        // 根据策略创建实例
        if (System.getSecurityManager() != null) {
            final Constructor<?> ctorToUse = constructorToUse;
            final Object[] argumentsToUse = argsToUse;
            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    return beanFactory.getInstantiationStrategy().instantiate(
                            mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
                }
            }, beanFactory.getAccessControlContext());
        }
        else {
            beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
                    mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
        }
        // 返回结果bw
        bw.setWrappedInstance(beanInstance);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

这个方法和代码块11的整体套路其实是类似的。当然,这也是这个系列文章中最后一个大方法,到这里,剩下的代码对你来说都不会再有什么难度~

9.3

// 使用默认构造方法
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        // 特权创建或者普通创建,最后都是在调用构造方法
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                }
            }, getAccessControlContext());
        }
        else {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

这个方法其实还是简单很多的,我没有把里面的再往出列,你可以去自己跟一下,相信此时你的实力,看这个方法对你来说还是小意思的。

至此,代码块8里面createBeanInstance方法也就讲完了,剩下的我们下一篇继续。

赞(0) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » 深入理解Spring IOC(五) 、 创建bean实例

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏