欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring啟動(dòng)過程中實(shí)例化部分代碼的分析之Bean的推斷構(gòu)造方法

 更新時(shí)間:2022年09月29日 10:34:29   作者:憂愁的chafry  
這篇文章主要介紹了Spring啟動(dòng)過程中實(shí)例化部分代碼的分析之Bean的推斷構(gòu)造方法,實(shí)例化這一步便是在doCreateBean方法的?instanceWrapper?=?createBeanInstance(beanName,?mbd,?args);這段代碼中,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧

針對(duì)實(shí)例化過程中會(huì)做什么的分析,其中主要的是怎么推斷出構(gòu)造方法,怎么進(jìn)行匹配

【1】前言

  實(shí)例化這一步便是在doCreateBean方法的 instanceWrapper = createBeanInstance(beanName, mbd, args);這段代碼中。

【2】對(duì)于實(shí)例化的疑問

  對(duì)于Spring中的beanBeanDefinition,需要通過實(shí)例化得到一個(gè)bean對(duì)象才會(huì)被放入容器中,而實(shí)例化就需要用到構(gòu)造方法。

  分析:一個(gè)類存在多個(gè)構(gòu)造方法,那么Spring進(jìn)行實(shí)例化時(shí),該如何去確定到底用哪個(gè)構(gòu)造方法呢?

    1. 如果開發(fā)者指定了想要使用的構(gòu)造方法,那么就用這個(gè)構(gòu)造方法。
    2. 如果開發(fā)者沒有指定想要使用的構(gòu)造方法,則看開發(fā)者有沒有讓Spring自動(dòng)去選擇構(gòu)造方法。
    3. 如果開發(fā)者也沒有讓Spring自動(dòng)去選擇構(gòu)造方法,則Spring利用無參構(gòu)造方法,如果沒有無參構(gòu)造方法,則報(bào)錯(cuò)。

  開發(fā)者可以通過什么方式來指定使用哪個(gè)構(gòu)造方法呢?

    1.通過xml中的<constructor-arg>標(biāo)簽,這個(gè)標(biāo)簽表示構(gòu)造方法參數(shù),所以可以根據(jù)這個(gè)確定想要使用的構(gòu)造方法的參數(shù)個(gè)數(shù),從而確定想要使用的構(gòu)造方法

    2.通過@Autowired注解,@Autowired注解可以寫在構(gòu)造方法上,所以哪個(gè)構(gòu)造方法上寫了@Autowired注解,表示開發(fā)者想使用哪個(gè)構(gòu)造方法,當(dāng)然,它和第一個(gè)方式的不同點(diǎn)是,通過xml的方式,我們直接指定了構(gòu)造方法的參數(shù)值,而通過@Autowired注解的方式,需要Spring通過byType+byName的方式去找到符合條件的bean作為構(gòu)造方法的參數(shù)值。

    3.如果Bean為注解@Lazy修飾的或者非單例的,可以通過getBean方法設(shè)置構(gòu)造方法的入?yún)ⅲ_(dá)到指定構(gòu)造方法的效果。如,applicationContext.getBean("BeanDemo", new CircularRefA());【同理,獲取beanDefinition,使用beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new CircularRefA());指定構(gòu)造方法參數(shù)】

【3】推斷構(gòu)造方法源碼分析

  1.主體代碼邏輯

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    /**
     * ----------0,校驗(yàn)部分------------
     */
    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());
    }

    /**
     * ----------1,通過Supplier實(shí)例化部分------------
     */
    // BeanDefinition中添加了Supplier,則調(diào)用Supplier來得到對(duì)象
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    /**
     * ----------2,通過工廠方法實(shí)例化部分------------
     */
    // @Bean對(duì)應(yīng)的BeanDefinition
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }


     /**
     * ----------3,用合適的構(gòu)造函數(shù)實(shí)例化部分------------
     *
     *  一個(gè)類可能有多個(gè)構(gòu)造器,所以Spring得根據(jù)參數(shù)個(gè)數(shù)、類型確定需要調(diào)用的構(gòu)造器。
     *  原型的BeanDefinition,會(huì)多次來創(chuàng)建Bean。故在使用構(gòu)造器創(chuàng)建實(shí)例后,Spring會(huì)將解析過后確定下來的構(gòu)造器或工廠方法保存在緩存中,避免再次創(chuàng)建相同bean時(shí)再次解析(節(jié)約時(shí)間)
     */
    boolean resolved = false; //對(duì)構(gòu)造器是否緩存了
    boolean autowireNecessary = false; //緩存的構(gòu)造器是否有參數(shù)
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                // autowireNecessary表示有沒有必要要進(jìn)行注入,比如當(dāng)前BeanDefinition用的是無參構(gòu)造方法,那么autowireNecessary為false,否則為true,表示需要給構(gòu)造方法參數(shù)注入值
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        // 如果確定了當(dāng)前BeanDefinition的構(gòu)造方法,那么看是否需要進(jìn)行對(duì)構(gòu)造方法進(jìn)行參數(shù)的依賴注入(構(gòu)造方法注入)
        if (autowireNecessary) {
            // 方法內(nèi)會(huì)拿到緩存好的構(gòu)造方法的入?yún)?
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            // 構(gòu)造方法已經(jīng)找到了,但是沒有參數(shù),那就表示是無參,直接進(jìn)行實(shí)例化
            return instantiateBean(beanName, mbd);
        }
    }

    //沒有緩存,從bean后置處理器中為自動(dòng)裝配尋找構(gòu)造方法
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // 找出最合適的默認(rèn)構(gòu)造方法
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        // 構(gòu)造函數(shù)自動(dòng)注入
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    /**
     * ----------4,使用默認(rèn)構(gòu)造函數(shù)構(gòu)造部分------------
     */
    // 不匹配以上情況,則直接使用無參構(gòu)造方法
    return instantiateBean(beanName, mbd);
}

  代碼說明

    createBeanInstance() 方法是 spring 實(shí)例化 bean 的核心代碼,它根據(jù)不同的情況會(huì)調(diào)用四種實(shí)例化方法:

      1)obtainFromSupplier() :通過 Supplier 實(shí)例化

      2)instantiateUsingFactoryMethod():通過工廠方法實(shí)例化

      3)autowireConstructor():用合適的構(gòu)造函數(shù)實(shí)例化

      4)instantiateBean():用無參構(gòu)造函數(shù)實(shí)例化

  2.局部分析代碼

    1)通過Supplier實(shí)例化部分解析

      代碼

// BeanDefinition中添加了Supplier,則調(diào)用Supplier來得到對(duì)象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
    return obtainFromSupplier(instanceSupplier, beanName);
}

      說明

        Spring提供的一種機(jī)制,雖然不常用,通過設(shè)置實(shí)現(xiàn)Supplier接口的類,返回一個(gè)另一種的對(duì)象,類似于FactoryBean的感覺。示例:

//在beanDefinition階段設(shè)置好
beanDefinition.setBeanClass(Student.class);
beanDefinition.setInstanceSupplier(new Supplier<Object>() {
    @Override
    public Object get() {
        return new UserServiceImpl1();
    }
});

//容器啟動(dòng)后嘗試獲取驗(yàn)證
applicationContext.getBean("student"); //返回new UserServiceImpl1()對(duì)象

    2)通過工廠方法實(shí)例化部分針(同時(shí)也是@Bean注解的處理)解析【如果存疑可以查看注解@Bean解析】

      代碼塊

// @Bean對(duì)應(yīng)的BeanDefinition
if (mbd.getFactoryMethodName() != null) {
    return instantiateUsingFactoryMethod(beanName, mbd, args);
}

      代碼深入部分:instantiateUsingFactoryMethod方法解析

protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
    // 使用factoryBean來實(shí)例化對(duì)象
    return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

//ConstructorResolver類#instantiateUsingFactoryMethod方法
//省略日志與異常
public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

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

    //通過beanDefinition獲取到factoryBeanName ,實(shí)際就是@Bean注解的方法所在的configuration類
    String factoryBeanName = mbd.getFactoryBeanName();
    //表示非靜態(tài)方法
    if (factoryBeanName != null) {
        if (factoryBeanName.equals(beanName)) {
            throw new BeanDefinitionStoreException(...);
        }
        factoryBean = this.beanFactory.getBean(factoryBeanName);

        // 該mbd已經(jīng)創(chuàng)建過了【代表這個(gè)邏輯已經(jīng)走過了】
        if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
            throw new ImplicitlyAppearedSingletonException();
        }
        factoryClass = factoryBean.getClass();
        isStatic = false;
    }
    else {//表示靜態(tài)方法
        // It's a static factory method on the bean class.
        if (!mbd.hasBeanClass()) {
            throw new BeanDefinitionStoreException(...);
        }
        factoryBean = null;
        factoryClass = mbd.getBeanClass();
        isStatic = true;
    }

    Method factoryMethodToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    //如果在調(diào)用getBean方法時(shí)有傳參,那就用傳的參作為@Bean注解的方法(工廠方法)的參數(shù), 一般懶加載的bean才會(huì)傳參,啟動(dòng)過程就實(shí)例化的實(shí)際上都沒有傳參
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }
    else {
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
            //不為空表示已經(jīng)使用過工廠方法,現(xiàn)在是再次使用工廠方法, 一般原型模式和Scope模式采用的上,直接使用該工廠方法和緩存的參數(shù)
            if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
                // Found a cached factory method...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        if (argsToResolve != null) {
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
        }
    }

    // 調(diào)用getBean方法沒有傳參,同時(shí)也是第一次使用工廠方法
    if (factoryMethodToUse == null || argsToUse == null) {
        
        factoryClass = ClassUtils.getUserClass(factoryClass);

        // 獲取configuration類的所有候選方法
        Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
        List<Method> candidateList = new ArrayList<>();
        for (Method candidate : rawCandidates) {
            // 查找到與工廠方法同名的候選方法,即有@Bean的同名方法
            if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
                candidateList.add(candidate);
            }
        }

        //當(dāng)與工廠方法同名的候選方法只有一個(gè),且調(diào)用getBean方法時(shí)沒有傳參,且沒有緩存過參數(shù),直接通過調(diào)用實(shí)例化方法執(zhí)行該候選方法
        if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
            Method uniqueCandidate = candidateList.get(0);
            if (uniqueCandidate.getParameterCount() == 0) {
                mbd.factoryMethodToIntrospect = uniqueCandidate;
                synchronized (mbd.constructorArgumentLock) {
                    mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                    mbd.constructorArgumentsResolved = true;
                    mbd.resolvedConstructorArguments = EMPTY_ARGS;
                }
                bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
                return bw;
            }
        }

        Method[] candidates = candidateList.toArray(new Method[0]);
        // 有多個(gè)與工廠方法同名的候選方法時(shí),進(jìn)行排序。public的方法會(huì)往前排,然后參數(shù)個(gè)數(shù)多的方法往前排
        AutowireUtils.sortFactoryMethods(candidates);

        ConstructorArgumentValues resolvedValues = null;
        boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Method> ambiguousFactoryMethods = null;

        int minNrOfArgs;
        // 如果調(diào)用getBean方法時(shí)有傳參,那么工廠方法最少參數(shù)個(gè)數(shù)要等于傳參個(gè)數(shù)
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        }
        else {
            //如果getBean的時(shí)候沒有傳參,如果BeanDefinition中有設(shè)置,則從BeanDefinition中獲取
            if (mbd.hasConstructorArgumentValues()) {
                ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                resolvedValues = new ConstructorArgumentValues();
                minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
            }
            else {
                minNrOfArgs = 0;
            }
        }

        LinkedList<UnsatisfiedDependencyException> causes = null;

        for (Method candidate : candidates) {
            Class<?>[] paramTypes = candidate.getParameterTypes();

            if (paramTypes.length >= minNrOfArgs) {
                ArgumentsHolder argsHolder;

                if (explicitArgs != null) {
                    // Explicit arguments given -> arguments length must match exactly.
                    if (paramTypes.length != explicitArgs.length) {
                        continue;
                    }
                    argsHolder = new ArgumentsHolder(explicitArgs);
                }
                else {
                    // 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);
                        }
                        //當(dāng)傳入的參數(shù)為空,需要根據(jù)工廠方法的參數(shù)類型注入相應(yīng)的bean
                        argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
                                paramTypes, paramNames, candidate, autowiring, candidates.length == 1);
                    }
                    catch (UnsatisfiedDependencyException ex) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
                        }
                        // Swallow and try next overloaded factory method.
                        if (causes == null) {
                            causes = new LinkedList<>();
                        }
                        causes.add(ex);
                        continue;
                    }
                }

                //計(jì)算工廠方法的權(quán)重
                int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                        argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                // Choose this factory method if it represents the closest match.
                if (typeDiffWeight < minTypeDiffWeight) {
                    /*
                    * 當(dāng)權(quán)重小時(shí),重新設(shè)置factoryMethodToUse 和argsHolderToUse ,argsToUse ,
                    * 并把當(dāng)前權(quán)重值設(shè)置為最小權(quán)重值,等待遍歷的下一個(gè)候選工廠方法比對(duì),
                    * 并且將ambiguousFactoryMethods (表示有含糊同樣權(quán)重的候選方法)設(shè)置為空
                    * */
                    factoryMethodToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousFactoryMethods = null;
                }

                /*
                * 當(dāng)遍歷到下一個(gè)候選方法的時(shí)候,已經(jīng)設(shè)置了factoryMethodToUse 且權(quán)重值與上一次的最小權(quán)重值相等時(shí),
                * ambiguousFactoryMethods填值,這個(gè)ambiguousFactoryMethods不為空表示有兩個(gè)候選方法的最小權(quán)重相等,
                * spring無法匹配出最適合的工廠方法,如果再繼續(xù)往下遍歷候選器,有更小的權(quán)重值,
                * 那ambiguousFactoryMethods會(huì)再次被設(shè)置為空
                * */
                else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
                        !mbd.isLenientConstructorResolution() &&
                        paramTypes.length == factoryMethodToUse.getParameterCount() &&
                        !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
                    if (ambiguousFactoryMethods == null) {
                        ambiguousFactoryMethods = new LinkedHashSet<>();
                        ambiguousFactoryMethods.add(factoryMethodToUse);
                    }
                    ambiguousFactoryMethods.add(candidate);
                }
            }
        }

        if (factoryMethodToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            List<String> argTypes = new ArrayList<>(minNrOfArgs);
            if (explicitArgs != null) {
                for (Object arg : explicitArgs) {
                    argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
                }
            }
            else if (resolvedValues != null) {
                Set<ValueHolder> valueHolders = new LinkedHashSet<>(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(...);
        }
        //返回類型不能為void
        else if (void.class == factoryMethodToUse.getReturnType()) {
            throw new BeanCreationException(...);
        }
        //存在含糊的兩個(gè)工廠方法,不知選哪個(gè)
        else if (ambiguousFactoryMethods != null) {
            throw new BeanCreationException(...);
        }

        if (explicitArgs == null && argsHolderToUse != null) {
            mbd.factoryMethodToIntrospect = factoryMethodToUse;
            argsHolderToUse.storeCache(mbd, factoryMethodToUse);
        }
    }

    //去實(shí)例化
    bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
    return bw;
}

    3)用合適的構(gòu)造函數(shù)實(shí)例化部分解析

boolean resolved = false; //對(duì)構(gòu)造器是否緩存了
boolean autowireNecessary = false; //緩存的構(gòu)造器是否有參數(shù)
//判斷是否有傳參,因?yàn)間etBean方法可以通過傳參指定構(gòu)造方法參數(shù)類型來進(jìn)行匹配(故這種對(duì)于參數(shù)的不確定是不能緩存的)
if (args == null) {
    synchronized (mbd.constructorArgumentLock) {
        if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            // autowireNecessary表示有沒有必要要進(jìn)行注入,比如當(dāng)前BeanDefinition用的是無參構(gòu)造方法,那么autowireNecessary為false,否則為true,表示需要給構(gòu)造方法參數(shù)注入值
            autowireNecessary = mbd.constructorArgumentsResolved;
        }
    }
}
if (resolved) {
    // 如果確定了當(dāng)前BeanDefinition的構(gòu)造方法,那么看是否需要進(jìn)行對(duì)構(gòu)造方法進(jìn)行參數(shù)的依賴注入(構(gòu)造方法注入)
    if (autowireNecessary) {
        // 方法內(nèi)會(huì)拿到緩存好的構(gòu)造方法的入?yún)?
        return autowireConstructor(beanName, mbd, null, null);
    }
    else {
        // 構(gòu)造方法已經(jīng)找到了,但是沒有參數(shù),那就表示是無參,直接進(jìn)行實(shí)例化
        return instantiateBean(beanName, mbd);
    }
}

//沒有緩存,從bean后置處理器中為自動(dòng)裝配尋找構(gòu)造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

//存在推斷出來的構(gòu)造方法集合
//BeanDefinition被設(shè)置為AUTOWIRE_CONSTRUCTOR
//BeanDefinition指定了構(gòu)造方法參數(shù)值
//getBean的時(shí)候傳入了構(gòu)造方法參數(shù)值
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    return autowireConstructor(beanName, mbd, ctors, args);
}

// 找出最合適的默認(rèn)構(gòu)造方法
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
    // 構(gòu)造函數(shù)自動(dòng)注入
    return autowireConstructor(beanName, mbd, ctors, null);
}

    代碼說明

      【1】針對(duì)determineConstructorsFromBeanPostProcessors方法分析

        代碼展示

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
    //如果類不為null,且存在InstantiationAwareBeanPostProcessor接口的處理器【其實(shí)用的不是它,而是他的子接口SmartInstantiationAwareBeanPostProcessor】
    if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                //真正存在實(shí)現(xiàn)的類是AutowiredAnnotationBeanPostProcessor類
                Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
                if (ctors != null) {
                    return ctors;
                }
            }
        }
    }
    return null;
}
//AutowiredAnnotationBeanPostProcessor類#determineCandidateConstructors方法
//日志和異常的輸出會(huì)被省略
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException {
    // 判斷是否檢測(cè)過
    if (!this.lookupMethodsChecked.contains(beanName)) {
        try {
            // 遍歷目標(biāo)類中的method,查看是否寫了@Lookup方法
            ReflectionUtils.doWithMethods(beanClass, method -> {
                Lookup lookup = method.getAnnotation(Lookup.class);
                if (lookup != null) {
                    Assert.state(this.beanFactory != null, "No BeanFactory available");
                    // 將當(dāng)前method封裝成LookupOverride并設(shè)置到BeanDefinition的methodOverrides中
                    LookupOverride override = new LookupOverride(method, lookup.value());
                    try {
                        RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
                        mbd.getMethodOverrides().addOverride(override);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(beanName,"...");
                    }
                }
            });
        }
        catch (IllegalStateException ex) {
            throw new BeanCreationException(beanName, "...", ex);
        }
        this.lookupMethodsChecked.add(beanName);
    }
    //先從緩存中獲取,看之前有沒有找過
    Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
    //緩存中沒有
    if (candidateConstructors == null) {
        // 加鎖,開始尋找
        synchronized (this.candidateConstructorsCache) {
            //再次從緩存中獲取,看被阻塞的時(shí)候沒有有線程已經(jīng)找好了存在緩存中(加鎖并雙重判斷的常規(guī)做法)
            candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            if (candidateConstructors == null) {
                Constructor<?>[] rawCandidates;
                try {
                    // 拿到所有的構(gòu)造方法
                    rawCandidates = beanClass.getDeclaredConstructors();
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "...", ex);
                }
                List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                // 用來記錄required為true的構(gòu)造方法,一個(gè)類中只能有一個(gè)required為true的構(gòu)造方法
                Constructor<?> requiredConstructor = null;
                // 用來記錄默認(rèn)無參的構(gòu)造方法
                Constructor<?> defaultConstructor = null;
                // kotlin相關(guān),不用管
                Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                int nonSyntheticConstructors = 0;
                // 遍歷每個(gè)構(gòu)造方法
                for (Constructor<?> candidate : rawCandidates) {
                    if (!candidate.isSynthetic()) {
                        // 記錄一下普通的構(gòu)造方法
                        nonSyntheticConstructors++;
                    }
                    else if (primaryConstructor != null) {
                        continue;
                    }
                    // 當(dāng)前遍歷的構(gòu)造方法是否寫了@Autowired
                    AnnotationAttributes ann = findAutowiredAnnotation(candidate);
                    //沒有@Autowired注解的情況
                    if (ann == null) {
                        // 如果beanClass是代理類,則得到被代理的類的類型
                        Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        if (userClass != beanClass) {
                            try {
                                //尋找被代理的類上的構(gòu)造方法有沒有@Autowired注解
                                Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                ann = findAutowiredAnnotation(superCtor);
                            }
                            catch (NoSuchMethodException ex) {}
                        }
                    }
                    /**
                     * 構(gòu)造方法如果有@Autowired注解,最后的操作是candidates.add(candidate),但如果出現(xiàn)兩種情況會(huì)拋出異常
                     *      a、如果之前有遍歷過@Autowired的構(gòu)造器,即requiredConstructor不為空
                     *      b、如果當(dāng)前的@Autowired的required屬性為true,不管之前遍歷過的@Autowired屬性是true還是false
                     */
                    if (ann != null) {
                        // 整個(gè)類中如果有一個(gè)required為true的構(gòu)造方法,那就不能有其他的加了@Autowired的構(gòu)造方法
                        if (requiredConstructor != null) {
                            throw new BeanCreationException(...);
                        }
                        //獲取該方法上的@Autowired注解的required屬性
                        boolean required = determineRequiredStatus(ann);
                        if (required) {
                            if (!candidates.isEmpty()) {
                                throw new BeanCreationException(...);
                            }
                            requiredConstructor = candidate;
                        }
                        // 記錄所有加了@Autowired的構(gòu)造方法,不管required是true還是false,如果默認(rèn)無參的構(gòu)造方法上也加了@Autowired,那么也會(huì)加到candidates中
                        candidates.add(candidate);
                    }
                    else if (candidate.getParameterCount() == 0) { //沒有注解且參數(shù)個(gè)數(shù)為0【即無參】
                        // 記錄唯一一個(gè)無參的構(gòu)造方法
                        defaultConstructor = candidate;
                    }
                    //但是這里沒有處理:有可能存在有參、并且沒有添加@Autowired的構(gòu)造方法。
                }
                //存儲(chǔ)有@Autowired注解的構(gòu)造方法的集合不為空
                if (!candidates.isEmpty()) {
                    // 如果不存在一個(gè)required為true的構(gòu)造方法,則所有required為false的構(gòu)造方法和無參構(gòu)造方法都是合格的
                    if (requiredConstructor == null) {
                        if (defaultConstructor != null) {
                            //無參構(gòu)造方法也添加到集合中
                            candidates.add(defaultConstructor);
                        }
                        else if (candidates.size() == 1 && logger.isInfoEnabled()) {
                            logger.info(...);
                        }
                    }
                    // 轉(zhuǎn)為數(shù)組
                    candidateConstructors = candidates.toArray(new Constructor<?>[0]);
                }
                // 沒有添加了@Autowired注解的構(gòu)造方法,并且類中只有一個(gè)構(gòu)造方法,并且是有參的
                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                    candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
                }
                // primaryConstructor不用管
                else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) { 
            candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
                }
                // primaryConstructor不用管
                else if (nonSyntheticConstructors == 1 && primaryConstructor != null) { candidateConstructors = new Constructor<?>[] {primaryConstructor};
                }
                else {
                    // 如果有多個(gè)有參、并且沒有添加@Autowired的構(gòu)造方法,是會(huì)返回空的
                    candidateConstructors = new Constructor<?>[0];
                }
                //將結(jié)果存入緩存
                this.candidateConstructorsCache.put(beanClass, candidateConstructors);
            }
        }
    }
    //有候選構(gòu)造器則返回,沒有返回null
    return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
返回結(jié)果預(yù)測(cè):
沒有加了@Autowired注解的構(gòu)造方法
    有多個(gè)構(gòu)造方法                             --》  返回null
    只有一個(gè)有參的構(gòu)造方法                     --》  返回此構(gòu)造方法
    只有一個(gè)無參的構(gòu)造方法                     --》  返回null
存在加了@Autowired注解的構(gòu)造方法
    只有一個(gè)required為true的構(gòu)造方法                      --》  返回此構(gòu)造方法
    有多個(gè)required為true的構(gòu)造方法                        --》  拋異常
    有一個(gè)required為true和其他的required為false的構(gòu)造方法  --》  視情況而定,可能會(huì)拋異常,可能會(huì)返回帶注解的構(gòu)造方法
    沒有required為true的構(gòu)造方法                          --》  返回所有required為false的構(gòu)造方法以及無參構(gòu)造方法

發(fā)現(xiàn)說明

1.在多個(gè)構(gòu)造方法上添加@Autowired注解會(huì)發(fā)生什么?

(1)因?yàn)锧Autowired注解的required屬性默認(rèn)為true,而根據(jù)源碼展示,如果有一個(gè)構(gòu)造方法上的@Autowired注解的required為true,那么后面的其他的構(gòu)造方法不管@Autowired注解的required屬性是什么都會(huì)報(bào)錯(cuò)。

(2)故如果要在多個(gè)構(gòu)造方法上添加@Autowired注解,那么必須將他們的required屬性設(shè)置為false。(這種更安全)

(3)要么就是將@Autowired注解的required屬性設(shè)置為true的構(gòu)造方法放到最后【僅限一個(gè)】

4)autowireConstructor方法分析

代碼展示

protected BeanWrapper autowireConstructor( String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
    return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

public ConstructorResolver(AbstractAutowireCapableBeanFactory beanFactory) {
    this.beanFactory = beanFactory;
    this.logger = beanFactory.getLogger();
}

//ConstructorResolver類#autowireConstructor方法
//省略一些異常和日志
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

    // 實(shí)例化BeanWrapper,是包裝bean的容器
    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    // 如果getBean()傳入了args,那構(gòu)造方法要用的入?yún)⒕椭苯哟_定好了
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }
    else {
         // 如果getBean()沒有傳入了參數(shù)
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            // 嘗試從緩存中獲取構(gòu)造方法
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // 從緩存中找到了構(gòu)造器,那么繼續(xù)從緩存中尋找緩存的構(gòu)造器參數(shù)
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    // 緩存沒有的話,那就獲取BeanDefinition指定的那些參數(shù)【可以沒有指定】
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }

        //argsToResolve不為空,即之前獲取到了參數(shù)【是從BeanDefinition指定的】要解析配置的參數(shù)
        if (argsToResolve != null) {
            // 解析參數(shù)類型,比如將配置的String類型轉(zhuǎn)換為list、boolean等類型
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
        }
    }

    // 如果沒有確定要使用的構(gòu)造方法,或者確定了構(gòu)造方法但是所要傳入的參數(shù)值沒有確定
    if (constructorToUse == null || argsToUse == null) {
        // 拿到傳入的構(gòu)造器數(shù)組
        Constructor<?>[] candidates = chosenCtors;
        //數(shù)組為空
        if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
                //使用public的構(gòu)造器(默認(rèn))或者所有構(gòu)造器
                candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }
            catch (Throwable ex) { throw new BeanCreationException(...); }
        }

        // 如果只有一個(gè)候選構(gòu)造方法,并且沒有指定所要使用的構(gòu)造方法參數(shù)值,并且該構(gòu)造方法是無參的,那就直接用這個(gè)無參構(gòu)造方法進(jìn)行實(shí)例化了
        if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
            Constructor<?> uniqueCandidate = candidates[0];
            if (uniqueCandidate.getParameterCount() == 0) {
                synchronized (mbd.constructorArgumentLock) {
                    mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                    mbd.constructorArgumentsResolved = true;
                    mbd.resolvedConstructorArguments = EMPTY_ARGS;
                }
                bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                return bw;
            }
        }

        //需要解析構(gòu)造函數(shù)標(biāo)志(當(dāng)構(gòu)造方法數(shù)組不為空,或是自動(dòng)裝配構(gòu)造函數(shù)時(shí))
        boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;

        // 確定要選擇的構(gòu)造方法的參數(shù)個(gè)數(shù)的最小值,后續(xù)判斷候選構(gòu)造方法的參數(shù)個(gè)數(shù)如果小于minNrOfArgs,則直接pass掉
        int minNrOfArgs;
        if (explicitArgs != null) {
            //如果直接傳了構(gòu)造方法參數(shù)值,那么所用的構(gòu)造方法的參數(shù)個(gè)數(shù)肯定不能少于
            minNrOfArgs = explicitArgs.length;
        }
        else {
            // 提取BeanDefinition中的配置的構(gòu)造函數(shù)參數(shù)
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            // 用于承載解析后的構(gòu)造函數(shù)參數(shù)的值
            resolvedValues = new ConstructorArgumentValues();
            // 能解析到的參數(shù)個(gè)數(shù)
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        // 排序給定的構(gòu)造函數(shù),public的構(gòu)造函數(shù)優(yōu)先,參數(shù)數(shù)量降序
        AutowireUtils.sortConstructors(candidates);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        LinkedList<UnsatisfiedDependencyException> causes = null;

        for (Constructor<?> candidate : candidates) {
            Class<?>[] paramTypes = candidate.getParameterTypes();

            // 如果已經(jīng)找到選用的構(gòu)造函數(shù)或者需要的參數(shù)個(gè)數(shù)小于當(dāng)前的構(gòu)造函數(shù)參數(shù)個(gè)數(shù)則終止,前面已經(jīng)經(jīng)過了排序操作
            if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
                break;
            }
            if (paramTypes.length < minNrOfArgs) {
                // 參數(shù)個(gè)數(shù)不相等
                continue;
            }

            ArgumentsHolder argsHolder;
            // 沒有通過getBean()指定構(gòu)造方法參數(shù)值
            if (resolvedValues != null) {
                try {
                    // 有參數(shù)則根據(jù)值構(gòu)造對(duì)應(yīng)參數(shù)類型的參數(shù)
                    String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);

                    if (paramNames == null) {
                        // 獲取參數(shù)名稱探索器
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            // 獲取指定構(gòu)造函數(shù)的參數(shù)名稱
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                    // 根據(jù)名稱和數(shù)據(jù)類型創(chuàng)建參數(shù)持有者
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                }
                catch (UnsatisfiedDependencyException ex) {
                    // 當(dāng)前正在遍歷的構(gòu)造方法找不到可用的入?yún)?duì)象,記錄一下
                    if (causes == null) {
                        causes = new LinkedList<>();
                    }
                    causes.add(ex);
                    continue;
                }
            }
            else {
                // 在調(diào)getBean方法是傳入了參數(shù)值,那就表示只能用對(duì)應(yīng)參數(shù)個(gè)數(shù)的構(gòu)造方法
                if (paramTypes.length != explicitArgs.length) {
                    continue;
                }
                // 構(gòu)造函數(shù)沒有參數(shù)的情況
                argsHolder = new ArgumentsHolder(explicitArgs);
            }

            // 當(dāng)前遍歷的構(gòu)造方法所需要的入?yún)?duì)象都找到了,根據(jù)參數(shù)類型和找到的參數(shù)對(duì)象計(jì)算出來一個(gè)匹配值,值越小越匹配(Lenient表示寬松模式)
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                    argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // 值越小越匹配
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            }
            // 值相等的情況下,記錄一下匹配值相同的構(gòu)造方法
            else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }
        // 遍歷結(jié)束

        // 如果沒有可用的構(gòu)造方法,就取記錄的最后一個(gè)異常并拋出
        if (constructorToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            throw new BeanCreationException(...);
        }
        // 如果有可用的構(gòu)造方法,但是有多個(gè)
        else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(...);
        }

        if (explicitArgs == null && argsHolderToUse != null) {
            // 將解析的構(gòu)造函數(shù)加入緩存
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    // 將構(gòu)造的實(shí)例加入BeanWrapper中
    bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
    return bw;
}

      發(fā)現(xiàn)說明

        1.autowireConstructor()大體流程 

         ?。?)先檢查是否指定了具體的構(gòu)造方法和構(gòu)造方法參數(shù)值,或者在BeanDefinition中緩存了具體的構(gòu)造方法或構(gòu)造方法參數(shù)值,如果存在那么則直接使用該構(gòu)造方法進(jìn)行實(shí)例化

         ?。?)如果沒有確定的構(gòu)造方法或構(gòu)造方法參數(shù)值,那么

              1)如果沒有確定的構(gòu)造方法,那么則找出類中所有的構(gòu)造方法

              2)如果只有一個(gè)無參的構(gòu)造方法,那么直接使用無參的構(gòu)造方法進(jìn)行實(shí)例化

              3)如果有多個(gè)可用的構(gòu)造方法或者當(dāng)前Bean需要自動(dòng)通過構(gòu)造方法注入

              4)根據(jù)所指定的構(gòu)造方法參數(shù)值,確定所需要的最少的構(gòu)造方法參數(shù)值的個(gè)數(shù)

              5)對(duì)所有的構(gòu)造方法進(jìn)行排序,參數(shù)個(gè)數(shù)多的在前面

              6)遍歷每個(gè)構(gòu)造方法

              7)如果不是調(diào)用getBean方法時(shí)所指定的構(gòu)造方法參數(shù)值,那么則根據(jù)構(gòu)造方法參數(shù)類型找值

              8)如果時(shí)調(diào)用getBean方法時(shí)所指定的構(gòu)造方法參數(shù)值,就直接利用這些值

              9)如果根據(jù)當(dāng)前構(gòu)造方法找到了對(duì)應(yīng)的構(gòu)造方法參數(shù)值,那么這個(gè)構(gòu)造方法就是可用的,但是不一定這個(gè)構(gòu)造方法就是最佳的,所以這里會(huì)涉及到是否有多個(gè)構(gòu)造方法匹配了同樣的值,這個(gè)時(shí)候就會(huì)用值和構(gòu)造方法類型進(jìn)行匹配程度的打分,找到一個(gè)最匹配的

        2.為什么分越少優(yōu)先級(jí)越高?

          (1)主要是計(jì)算找到的bean和構(gòu)造方法參數(shù)類型匹配程度有多高。

          (2)示例:假設(shè)bean的類型為A,A的父類是B,B的父類是C,同時(shí)A實(shí)現(xiàn)了接口D 如果構(gòu)造方法的參數(shù)類型為A,那么完全匹配,得分為0 如果構(gòu)造方法的參數(shù)類型為B,那么得分為2 如果構(gòu)造方法的參數(shù)類型為C,那么得分為4 如果構(gòu)造方法的參數(shù)類型為D,那么得分為

Object[] objects = new Object[]{new A()};
// 0
System.out.println(MethodInvoker.getTypeDifferenceWeight(new Class[]{A.class}, objects));
// 2
System.out.println(MethodInvoker.getTypeDifferenceWeight(new Class[]{B.class}, objects));
// 4
System.out.println(MethodInvoker.getTypeDifferenceWeight(new Class[]{C.class}, objects));
// 1
System.out.println(MethodInvoker.getTypeDifferenceWeight(new Class[]{D.class}, objects));

         ?。?)所以,我們可以發(fā)現(xiàn),越匹配分?jǐn)?shù)越低

    5)無參構(gòu)造方法instantiateBean方法分析

//AbstractAutowireCapableBeanFactory類#instantiateBean方法
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged( (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this), getAccessControlContext());
        }
        else {
            //獲取實(shí)例化策略并且進(jìn)行實(shí)例化操作
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
        }
        // 包裝成BeanWrapper
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

//SimpleInstantiationStrategy類#instantiate方法
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // bd對(duì)象定義中,是否包含MethodOverride列表,spring中有兩個(gè)標(biāo)簽參數(shù)會(huì)產(chǎn)生MethodOverrides,分別是lookup-method,replaced-method
    // 沒有MethodOverrides對(duì)象,可以直接實(shí)例化
    if (!bd.hasMethodOverrides()) {
        // 實(shí)例化對(duì)象的構(gòu)造方法
        Constructor<?> constructorToUse;
        // 鎖定對(duì)象,使獲得實(shí)例化構(gòu)造方法線程安全
        synchronized (bd.constructorArgumentLock) {
            // 查看bd對(duì)象里使用否含有構(gòu)造方法
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            // 如果沒有
            if (constructorToUse == null) {
                // 從bd中獲取beanClass
                final Class<?> clazz = bd.getBeanClass();
                // 如果要實(shí)例化的beanDefinition是一個(gè)接口,則直接拋出異常
                if (clazz.isInterface()) {
                    throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                    // 獲取系統(tǒng)安全管理器
                    if (System.getSecurityManager() != null) {
                        constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                    }
                    else {
                        // 獲取默認(rèn)的無參構(gòu)造器
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    // 獲取到構(gòu)造器之后將構(gòu)造器賦值給bd中的屬性
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
            }
        }
        // 通過反射生成具體的實(shí)例化對(duì)象
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // 必須生成cglib子類
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
    throws NoSuchMethodException, SecurityException { checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
    return getConstructor0(parameterTypes, Member.DECLARED);
}

private Constructor<T> getConstructor0(Class<?>[] parameterTypes, int which) throws NoSuchMethodException {
    //獲取所有的構(gòu)造器
    Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
    //遍歷構(gòu)造器,匹配的返回
    for (Constructor<T> constructor : constructors) {
        if (arrayContentsEq(parameterTypes,
                            constructor.getParameterTypes())) {
            return getReflectionFactory().copyConstructor(constructor);
        }
    }
    throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
}
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new CircularRefA());

到此這篇關(guān)于Spring啟動(dòng)過程中實(shí)例化部分代碼的分析之Bean的推斷構(gòu)造方法的文章就介紹到這了,更多相關(guān)Spring Bean的推斷構(gòu)造方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java深入學(xué)習(xí)圖形用戶界面GUI之布局管理器

    Java深入學(xué)習(xí)圖形用戶界面GUI之布局管理器

    本文章向大家介紹Java GUI布局管理器,主要包括布局管理器使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-05-05
  • Ubuntu快速安裝jdk的教程

    Ubuntu快速安裝jdk的教程

    這篇文章主要為大家詳細(xì)介紹了Ubuntu快速安裝jdk的教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • java后臺(tái)防止表單重復(fù)提交方法詳解

    java后臺(tái)防止表單重復(fù)提交方法詳解

    這篇文章主要介紹了后臺(tái)防止表單重復(fù)提交,利用Session防止表單重復(fù)提交,判斷請(qǐng)求url和數(shù)據(jù)是否和上一次相同,利用Spring AOP和redis的鎖需要的朋友可以參考下
    2022-12-12
  • Java設(shè)計(jì)模式之命令模式詳細(xì)解析

    Java設(shè)計(jì)模式之命令模式詳細(xì)解析

    這篇文章主要介紹了Java設(shè)計(jì)模式之命令模式詳細(xì)解析,命令模式將請(qǐng)求封裝成對(duì)象,以便使用不同的請(qǐng)求、隊(duì)列或者日志來參數(shù)化其他對(duì)象,同時(shí)也支持可撤銷的操作,需要的朋友可以參考下
    2024-01-01
  • Java過濾器與監(jiān)聽器間區(qū)別與聯(lián)系

    Java過濾器與監(jiān)聽器間區(qū)別與聯(lián)系

    監(jiān)聽器是一個(gè)接口內(nèi)容由我們實(shí)現(xiàn),會(huì)在特定時(shí)間被調(diào)用,監(jiān)聽器用于監(jiān)聽web應(yīng)用中三大域?qū)ο?request,session,application),信息的創(chuàng)建,銷毀,增加,修改,刪除等動(dòng)作的發(fā)生,然后做出相應(yīng)的響應(yīng)處理
    2023-01-01
  • Java中常見的4種限流算法詳解

    Java中常見的4種限流算法詳解

    這篇文章主要介紹了Java中常見的4種限流算法詳解,FixedWindowRateLimiter 類表示一個(gè)固定窗口限流器,使用 limit 和 interval 參數(shù)分別表示限制請(qǐng)求數(shù)量和時(shí)間間隔,缺點(diǎn)是短時(shí)間內(nèi)可能會(huì)流量翻倍,需要的朋友可以參考下
    2023-12-12
  • Java面試題解析之判斷以及防止SQL注入

    Java面試題解析之判斷以及防止SQL注入

    這篇文章主要介紹了Java面試題解析之判斷以及防止SQL注入,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • 淺談java泛型的作用及其基本概念

    淺談java泛型的作用及其基本概念

    下面小編就為大家?guī)硪黄獪\談java泛型的作用及其基本概念。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • 詳解jvm雙親委派機(jī)制

    詳解jvm雙親委派機(jī)制

    雙親委派機(jī)制保證了核心類的安全,確保不會(huì)被修改,也保證了不會(huì)加載到重復(fù)的字節(jié)碼文件,這篇文章主要介紹了jvm雙親委派機(jī)制詳解,需要的朋友可以參考下
    2022-11-11
  • SpringBoot打印系統(tǒng)執(zhí)行的sql語(yǔ)句及日志配置指南

    SpringBoot打印系統(tǒng)執(zhí)行的sql語(yǔ)句及日志配置指南

    這篇文章主要給大家介紹了關(guān)于SpringBoot打印系統(tǒng)執(zhí)行的sql語(yǔ)句及日志配置的相關(guān)資料,在Java SpringBoot項(xiàng)目中如果使用了Mybatis框架,默認(rèn)情況下執(zhí)行的所有SQL操作都不會(huì)打印日志,需要的朋友可以參考下
    2023-10-10

最新評(píng)論