• bean的创建(五)第二部分 寻找bean的工厂方法实例化


    instanceWrapper = createBeanInstance(beanName, mbd, args);
    
    AbstractAutowireCapableBeanFactory.createBeanInstance
    
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
            // Make sure bean class is actually resolved at this point.确保实际已经解析了beanClass,如果是表达式,会进行表达式的运算得到className
            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());
            }
    
    //如果存在工厂方法,那么说明需要通过静态工厂的方式获取bean
            if (mbd.getFactoryMethodName() != null)  {
                return instantiateUsingFactoryMethod(beanName, mbd, args);
            }
    
            // Shortcut when re-creating the same bean...
            boolean resolved = false;
            boolean autowireNecessary = false;
            if (args == null) {
                synchronized (mbd.constructorArgumentLock) {
                    if (mbd.resolvedConstructorOrFactoryMethod != null) {
                        resolved = true;
                        autowireNecessary = mbd.constructorArgumentsResolved;
                    }
                }
            }
            if (resolved) {
                if (autowireNecessary) {
                    return autowireConstructor(beanName, mbd, null, null);
                }
                else {
                    return instantiateBean(beanName, mbd);
                }
            }
    
            // Need to determine the constructor...
            Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
            if (ctors != null ||
                    mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
                return autowireConstructor(beanName, mbd, ctors, args);
            }
    
            // No special handling: simply use no-arg constructor.
            return instantiateBean(beanName, mbd);
        }
    
    
    AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod
    
    protected BeanWrapper instantiateUsingFactoryMethod(
                String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
    
            return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
        }
    
    ConstructorResolver.instantiateUsingFactoryMethod
    
    public BeanWrapper instantiateUsingFactoryMethod(
                final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {
    
            BeanWrapperImpl bw = new BeanWrapperImpl();
    //初始化这个bean包装器,内部给这个包装器设置了类型转化器和自定的转化器
            this.beanFactory.initBeanWrapper(bw);
    
            Object factoryBean;
            Class<?> factoryClass;
            boolean isStatic;
    
            String factoryBeanName = mbd.getFactoryBeanName();
    //如果存在factoryBeanName   比如<bean id="helloWorld" factory-bean="helloWorld" factory-method="getSayHi"></bean>
            if (factoryBeanName != null) {
    //如果工厂bean的名字和自己相同,那么直接抛错
                if (factoryBeanName.equals(beanName)) {
                    throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                            "factory-bean reference points back to the same bean definition");
                }
    //使用getBean获取到依赖的那个工厂bean
                factoryBean = this.beanFactory.getBean(factoryBeanName);
                if (factoryBean == null) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null");
                }
                if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
                    throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared " +
                            "through the creation of the factory bean that its bean definition points to");
                }
                factoryClass = factoryBean.getClass();
                isStatic = false;
            }
            else {
                // It's a static factory method on the bean class.
                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 {
                Object[] argsToResolve = null;
                synchronized (mbd.constructorArgumentLock) {
    //获取已经解析后的构造器或者工厂方法
                    factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
                    //如果已经解析好了,那么尝试从缓存中获取参数
    if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
                        // Found a cached factory method...
                        argsToUse = mbd.resolvedConstructorArguments;
    //如果缓存中没有,那么就从准备的(也就是解析配置文件时,BeanDefinition存储的参数)构造参数中获取,这个时候的参数还是原始(配置文件中)的,没有进行类型转换的参数
                        if (argsToUse == null) {
                            argsToResolve = mbd.preparedConstructorArguments;
                        }
                    }
                }
                if (argsToResolve != null) {
    //解析准备的配置参数
                    argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
                }
            }
    //如果没有缓存,那么说明这是第一次访问,需要从头开始解析
            if (factoryMethodToUse == null || argsToUse == null) {
                // Need to determine the factory method...
                // Try all methods with this name to see if they match the given arguments.
    //判断是否被cglib代理过的,如果代理过,那么就返回其父类
                factoryClass = ClassUtils.getUserClass(factoryClass);
    //获取这个类定义的所有方法
                Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
                List<Method> candidateSet = new ArrayList<Method>();
                for (Method candidate : rawCandidates) {
    //获取工厂方法
                    if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
                        candidateSet.add(candidate);
                    }
                }
                Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);
                //给重载的方法排序,public修饰和参数长的排在前面
    AutowireUtils.sortFactoryMethods(candidates);
    
                ConstructorArgumentValues resolvedValues = null;
                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 {
                    // We don't have arguments passed in programmatically, so we need to resolve the
                    // arguments specified in the constructor arguments held in the bean definition.
    //如果用户没有传递参数进来,那么我们需要获取配置的参数
                    ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                    resolvedValues = new ConstructorArgumentValues();
    //解析构造参数,通过BeanDefinitionValueResolver进行解析,解析好后放置到resolvedValues中,这里主要是将beanref的解析好和以下表达式什么的,没有进行参数类型的转换。
                    minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
                }
    
                List<Exception> causes = null;
    
                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);
                                }
    //由于实际方法的参数和配置的参数之间存在位置,类型需要转化的问题,所以需要尝试换成符合对应方法的参数
                                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);
                                }
                                if (i == candidates.length - 1 && argsHolderToUse == null) {
                                    if (causes != null) {
                                        for (Exception cause : causes) {
                                            this.beanFactory.onSuppressedException(cause);
                                        }
                                    }
                                    throw ex;
                                }
                                else {
                                    // Swallow and try next overloaded factory method.
                                    if (causes == null) {
                                        causes = new LinkedList<Exception>();
                                    }
                                    causes.add(ex);
                                    continue;
                                }
                            }
                        }
    
                        else {
    //如果配置里面没有参数,那么就使用用户设置的参数
                            // Explicit arguments given -> arguments length must match exactly.
                            if (paramTypes.length != explicitArgs.length) {
                                continue;
                            }
                            argsHolder = new ArgumentsHolder(explicitArgs);
                        }
    
                        int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                                argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                        // Choose this factory method if it represents the closest match.
                        if (typeDiffWeight < minTypeDiffWeight) {
                            factoryMethodToUse = candidate;
                            argsHolderToUse = argsHolder;
                            argsToUse = argsHolder.arguments;
                            minTypeDiffWeight = typeDiffWeight;
                            ambiguousFactoryMethods = null;
                        }
                        // Find out about ambiguity: In case of the same type difference weight
                        // for methods with the same number of parameters, collect such candidates
                        // and eventually raise an ambiguity exception.
                        // However, only perform that check in non-lenient constructor resolution mode,
                        // and explicitly ignore overridden methods (with the same parameter signature).
                        else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
                                !mbd.isLenientConstructorResolution() &&
                                paramTypes.length == factoryMethodToUse.getParameterTypes().length &&
                                !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
                            if (ambiguousFactoryMethods == null) {
                                ambiguousFactoryMethods = new LinkedHashSet<Method>();
                                ambiguousFactoryMethods.add(factoryMethodToUse);
                            }
                            ambiguousFactoryMethods.add(candidate);
                        }
                    }
                }
    
                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") + ".");
                }
                else if (void.class == factoryMethodToUse.getReturnType()) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Invalid factory method '" + mbd.getFactoryMethodName() +
                            "': needs to have a non-void return type!");
                }
                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);
                }
    
                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 = this.beanFactory.getInstantiationStrategy().instantiate(
                            mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
                }
    
                if (beanInstance == null) {
                    return null;
                }
                bw.setWrappedInstance(beanInstance);
                return bw;
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Bean instantiation via factory method failed", ex);
            }
        }
    
    
    ConstructorResolver.resolvePreparedArguments
    
    private Object[] resolvePreparedArguments(
                String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {
    //获取构造方法或者工厂方法的参数类型
            Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
                    ((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
    //获取自定义的类型转化器,如果没有就是用bean包装器·,这个包装器在上面已经注册了默认的转化器和自定的转化器。
            TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
                    this.beanFactory.getCustomTypeConverter() : bw);、
    //构建BeanDefinition值的解析器,用于转化value
            BeanDefinitionValueResolver valueResolver =
                    new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
            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());
    //参数是AutowiredArgumentMarker只只是个标记类,标记为自动装配的参数,这里会解析@Value注解的参数,还有会根据字段的类型去包装成某些延迟获取数据的对象,比如DependencyObjectFactory(依赖工厂bean,这种类型字段可以通过getObject获取数据),这里是方法参数的获取所以不用去管field的。最后内部会通过DefaultListableBeanFactory.doResolveDependency方法根据参数类型去获取bean
                if (argValue instanceof AutowiredArgumentMarker) {
                    argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
                }
    //这种类型数据一般是在解析xml配置的时候生成的,比如xml中的ref指定的bean会包装成RuntimeBeanReference,当spring看到这种类型的时候就知道,我要去BeanFactory中寻找叫这个名字的bean
                else if (argValue instanceof BeanMetadataElement) {
    //使用上面new出来的BeanDefinitionValueResolver进行解析
                    argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
                }
    //如果只是普通的字符串,那么经过表达式解析器之后直接返回
                else if (argValue instanceof String) {
                    argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
                }
                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;
        }
    
    
    
    DefaultListableBeanFactory.resolveDependency
    
    public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
                Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    //获取参数名
            descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
    //如果对应的字段或参数类型是Option类型的,那么创建Option,对应的值用get获取,其实内部的值依然是调用 doResolveDependency获取的
            if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
                return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
            }
    //如果这个字段或参数是对象工厂,那么返回依赖工厂,对应的值用个getObject获取
            else if (ObjectFactory.class == descriptor.getDependencyType()) {
                return new DependencyObjectFactory(descriptor, beanName);
            }
    //如果这个字段或参数类型为javax.inject.Provider,那么返回DependencyProvider,通过get获取值
            else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
                return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
            }
            else {
                Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
                if (result == null) {
    //解析依赖
                    result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
                }
                return result;
            }
        }
    
    DefaultListableBeanFactory.doResolveDependency
    
    public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
                Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    //获取字段或方法参数的类型
            Class<?> type = descriptor.getDependencyType();
    //获取@Value注解的值
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
            if (value != null) {
                if (value instanceof String) {
    //如果从@Value中获取到了数据,那么就解析${}占位符。
                    String strVal = resolveEmbeddedValue((String) value);
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
    //动态语言解析
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    //转换类型后返回
                return (descriptor.getField() != null ?
                        converter.convertIfNecessary(value, type, descriptor.getField()) :
                        converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
            }
    //如果是数组,那么获取到对应数组类型,然后到BeanFactory中获取到对应的类型
            if (type.isArray()) {
                Class<?> componentType = type.getComponentType();
                DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
                targetDesc.increaseNestingLevel();
    //获取符合类型的候选的对象
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc);
                if (matchingBeans.isEmpty()) {
    //如果这个字段或参数是必须的,又没有值,那么只好报错了
                    if (descriptor.isRequired()) {
                        raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
                    }
                    return null;
                }
                if (autowiredBeanNames != null) {
                    autowiredBeanNames.addAll(matchingBeans.keySet());
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    //转换类型
                Object result = converter.convertIfNecessary(matchingBeans.values(), type);
                if (getDependencyComparator() != null && result instanceof Object[]) {
                    Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
                }
                return result;
            }
    //处理集合类型
            else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
                Class<?> elementType = descriptor.getCollectionType();
                if (elementType == null) {
                    if (descriptor.isRequired()) {
                        throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
                    }
                    return null;
                }
                DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
                targetDesc.increaseNestingLevel();
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc);
                if (matchingBeans.isEmpty()) {
                    if (descriptor.isRequired()) {
                        raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
                    }
                    return null;
                }
                if (autowiredBeanNames != null) {
                    autowiredBeanNames.addAll(matchingBeans.keySet());
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                Object result = converter.convertIfNecessary(matchingBeans.values(), type);
                if (getDependencyComparator() != null && result instanceof List) {
                    Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
                }
                return result;
            }
    、        //处理Map类型
            else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
                Class<?> keyType = descriptor.getMapKeyType();
                if (String.class != keyType) {
                    if (descriptor.isRequired()) {
                        throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
                                "] must be [java.lang.String]");
                    }
                    return null;
                }
                Class<?> valueType = descriptor.getMapValueType();
                if (valueType == null) {
                    if (descriptor.isRequired()) {
                        throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
                    }
                    return null;
                }
                DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
                targetDesc.increaseNestingLevel();
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc);
                if (matchingBeans.isEmpty()) {
                    if (descriptor.isRequired()) {
                        raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
                    }
                    return null;
                }
                if (autowiredBeanNames != null) {
                    autowiredBeanNames.addAll(matchingBeans.keySet());
                }
                return matchingBeans;
            }
            else {
                Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
                if (matchingBeans.isEmpty()) {
                    if (descriptor.isRequired()) {
                        raiseNoSuchBeanDefinitionException(type, "", descriptor);
                    }
                    return null;
                }
    //如果匹配的bean大于一个,那么就查看是否配置了primary属性,如果有就使用primary的那个,没有就报错。
                if (matchingBeans.size() > 1) {
                    String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                    if (primaryBeanName == null) {
                        throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
                    }
                    if (autowiredBeanNames != null) {
                        autowiredBeanNames.add(primaryBeanName);
                    }
                    return matchingBeans.get(primaryBeanName);
                }
                // We have exactly one match.
                Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
                if (autowiredBeanNames != null) {
                    autowiredBeanNames.add(entry.getKey());
                }
                return entry.getValue();
            }
        }
  • 相关阅读:
    Asp.Net Core Web应用程序—探索
    C# -Asp.Net.SignalR.Core之Hub
    C#净化版WebApi框架
    C#-Xamarin的Activity传值与Fragment引用
    C#-Xamarin利用ZXing.Net.Mobile进行扫码
    Junit4 架构设计系列(1): Request,ClassRequest 和 RunnerBuilder
    非常好用的正则表达式"\s+"
    简单易懂, JUnit 框架问答
    JUnit扩展:引入新注解Annotation
    让你的自动化代码更健壮
  • 原文地址:https://www.cnblogs.com/honger/p/10389852.html
Copyright © 2020-2023  润新知