Spring全家桶源码解析--2.5 Spring bean 推断构造方法创建bean


前言

Spring 通过构造方法完成对象的创建,那么当改类中有多个构造方法时,spring 会选用哪个构造方法来创建对象;


一、构造方法创建对象过程

1.1 Spring 中创建实例的入口:

AbstractAutowireCapableBeanFactory.createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 获取bean class 对象,通过类的class 对象可以获取其构造方法,及其类的属性
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        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());
        } else {
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return this.obtainFromSupplier(instanceSupplier, beanName);
            } else if (mbd.getFactoryMethodName() != null) {
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            } else {
                boolean resolved = false;
                boolean autowireNecessary = false;
                if (args == null) {
                    synchronized(mbd.constructorArgumentLock) {
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }
				/**
				** 下面代码是重点
				**/	
                if (resolved) {
                	// 如果已经被解析过 则直接使用之前缓存的完成对象的创建 ,否则使用无参构造方法 创建对象
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
	                /**
					** 下面代码是重点
					**/	
                	// 获取推断构造方法
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    // 如没有推断出米构造方法,并且 autowiremode 也不是AUTOWIRE_CONSTRUCTOR(自动选择构造方法),
                    // 没有通过BeanDefinition 和 getbean 的方式传入参数
                    // 在项目中一般我们在获取bean 对象时直接getbean 不会进行传参,也不会定义AUTOWIRE_CONSTRUCTOR
                    // 所以这里一旦没有推断出来构造方法则 使用默认的无参构造方法
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                    	// 没有获取到推断构造方法,则使用默认的无参构造方法
                        ctors = mbd.getPreferredConstructors();
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                    	// 如果获取到了推断构造方法,多个构造方法或者通过spring 自动判断加载构造方法
                  
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            }
        }
    }

1.2 构造方法获取:

this.determineConstructorsFromBeanPostProcessors(beanClass, beanName)

@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
     if (beanClass != null && this.hasInstantiationAwareBeanPostProcessors()) {
         Iterator var3 = this.getBeanPostProcessorCache().smartInstantiationAware.iterator();

         while(var3.hasNext()) {
             SmartInstantiationAwareBeanPostProcessor bp = (SmartInstantiationAwareBeanPostProcessor)var3.next();
             Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
             if (ctors != null) {
                 return ctors;
             }
         }
     }

     return null;
 }

bp.determineCandidateConstructors(beanClass, beanName)

@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeanCreationException {
    if (!this.lookupMethodsChecked.contains(beanName)) {
        if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
            try {
                Class<?> targetClass = beanClass;

                do {
                    ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
                        Lookup lookup = (Lookup)method.getAnnotation(Lookup.class);
                        if (lookup != null) {
                            Assert.state(this.beanFactory != null, "No BeanFactory available");
                            LookupOverride override = new LookupOverride(method, lookup.value());

                            try {
                                RootBeanDefinition mbd = (RootBeanDefinition)this.beanFactory.getMergedBeanDefinition(beanName);
                                mbd.getMethodOverrides().addOverride(override);
                            } catch (NoSuchBeanDefinitionException var6) {
                                throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition");
                            }
                        }

                    });
                    targetClass = targetClass.getSuperclass();
                } while(targetClass != null && targetClass != Object.class);
            } catch (IllegalStateException var22) {
                throw new BeanCreationException(beanName, "Lookup method resolution failed", var22);
            }
        }

        this.lookupMethodsChecked.add(beanName);
    }

    Constructor<?>[] candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
    if (candidateConstructors == null) {
        synchronized(this.candidateConstructorsCache) {
            candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
            if (candidateConstructors == null) {
                Constructor[] rawCandidates;
                try {
                	// 这里获取了该类的所有构造方法不管是私有的还是公有的
                    rawCandidates = beanClass.getDeclaredConstructors();
                } catch (Throwable var20) {
                    throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", var20);
                }

                List<Constructor<?>> candidates = new ArrayList(rawCandidates.length);
                // 使用@Autowired 表中的构造方法
                Constructor<?> requiredConstructor = null;
                // 默认无参的构造方法
                Constructor<?> defaultConstructor = null;
                Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                int nonSyntheticConstructors = 0;
                Constructor[] var11 = rawCandidates;
                int var12 = rawCandidates.length;
                int var13 = 0;

                while(true) {
                // 刚开始  var13  = 0 不进入改判断 先到 label144 为 requiredConstructor
                  // defaultConstructor ,candidates 赋值
                    if (var13 >= var12) { 
                  
                        if (!candidates.isEmpty()) {
                        	// 当有被@Autowired 标注的构造方法,当存在有 require = true 的构造方法 则返回改方法
                            if (requiredConstructor == null) {
                           		
                            	// 如果没有 require = true 的构造方法
                                if (defaultConstructor != null) {
                                	//  如果有默认的无参构造方法,则使用默认的无参构造方法
                                    candidates.add(defaultConstructor);
                                } else if (candidates.size() == 1 && this.logger.isInfoEnabled()) {
                                	//
                                    this.logger.info("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - this constructor is effectively required since there is no default constructor to fall back to: " + candidates.get(0));
                                }
                            }
							// 返回构造方法
                            candidateConstructors = (Constructor[])candidates.toArray(new Constructor[0]);
                        } else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                        	// 当只有一个有参的构造方法则直接返回改构造方法
                            candidateConstructors = new Constructor[]{rawCandidates[0]};
                        } else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
                            candidateConstructors = new Constructor[]{primaryConstructor, defaultConstructor};
                        } else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
                            candidateConstructors = new Constructor[]{primaryConstructor};
                        } else {
                            candidateConstructors = new Constructor[0];
                        }

                        this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                        break;
                    }

                    label144: {
                    	// 遍历获取构造方法
                        Constructor<?> candidate = var11[var13];
                        if (!candidate.isSynthetic()) {
                            ++nonSyntheticConstructors;
                        } else if (primaryConstructor != null) {
                            break label144;
                        }
						// 是否标注了@Autowired 注解
                        MergedAnnotation<?> ann = this.findAutowiredAnnotation(candidate);
                        if (ann == null) {
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            if (userClass != beanClass) {
                                try {
                                    Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                    ann = this.findAutowiredAnnotation(superCtor);
                                } catch (NoSuchMethodException var19) {
                                }
                            }
                        }

                        if (ann != null) {
                           // 只能有一个@Autowired(required = true)   的构造方法并且其他的构造方法不能标注@Autowired 注解
                           //  ,但是构造方法可以全不都是标注@Autowired(required = false) 
                        	// 如果已经有标注了@Autowired 并且数true注解的构造方法
                            if (requiredConstructor != null) {
                            	// 如果已经有了标准 @Autowired(required = true) 则报错
                                throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor);
                            }
							// 获取 required  是否为 true
                            boolean required = this.determineRequiredStatus(ann);
                            if (required) {
                            	// 如果为true,并且已经有了 被@Autowired 标准的构造方法 不论是否 为true 和false 则报错
                                if (!candidates.isEmpty()) {
                                    throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate);
                                }
								// 
                                requiredConstructor = candidate;
                            }
							// 将带有  @Autowired 标准的构造放入集合中
                            candidates.add(candidate);
                        } else if (candidate.getParameterCount() == 0) {
                        	// 如果没有标注@Autowired 注解并且 没有参数,则为无参的构方法
                            defaultConstructor = candidate;
                        }
                    }

                    ++var13;
                }
            }
        }
    }

    return candidateConstructors.length > 0 ? candidateConstructors : null;
}

在这里插入图片描述

1.3 构造方法确定:

ConstructorResolver.autowireConstructor

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);
    // 要使用的构造和参数
    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        Object[] argsToResolve = null;
        synchronized(mbd.constructorArgumentLock) {
            constructorToUse = (Constructor)mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }

        if (argsToResolve != null) {
            argsToUse = this.resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
        }
    }

    if (constructorToUse == null || argsToUse == null) {
        Constructor<?>[] candidates = chosenCtors;
        if (chosenCtors == null) {
            Class<?> beanClass = mbd.getBeanClass();

            try {
            	// 如果没有构造方法则重新获取下构造方法
                candidates = mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors();
            } catch (Throwable var26) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", var26);
            }
        }
		// 只有一个的构造方法,并且getBean 没有传递参数,并且也没有通过beanDefinition 构建参数,则直接使用这个构造方法
        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(this.instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                return bw;
            }
        }
		// 多个构造方法或者通过spring 自动判断加载构造方法
        boolean autowiring = chosenCtors != null || mbd.getResolvedAutowireMode() == 3;
        ConstructorArgumentValues resolvedValues = null;
        // 构造方法参数个数的最小值
        int minNrOfArgs;
        if (explicitArgs != null) {
        	// 如果 getbean 有传入参数则直接使用
            minNrOfArgs = explicitArgs.length;
        } else {
 
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
            // 且 getbean 没有传递参数 通过beanDefinition 构建参数,则得到最小参数的构造方法
            minNrOfArgs = this.resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }
		// 多个构造方法先进行排序:public 的在前面,参数多的在前面
        AutowireUtils.sortConstructors(candidates);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        Deque<UnsatisfiedDependencyException> causes = null;
        Constructor[] var16 = candidates;
        int var17 = candidates.length;

        for(int var18 = 0; var18 < var17; ++var18) {
            Constructor<?> candidate = var16[var18];
            int parameterCount = candidate.getParameterCount();
            // 遍历构造方法,如果之前缓存了构造方法 并且构造方法的参数大于当前构造方法的参数则直接返回,
            // 使用之前缓存的构造方法创建对象;
            if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
                break;
            }

            if (parameterCount >= minNrOfArgs) {
            	// 获取构造方法参数的类型和名字:
                Class<?>[] paramTypes = candidate.getParameterTypes();
                ArgumentsHolder argsHolder;
                if (resolvedValues != null) {
                    try {
                        String[] paramNames = ConstructorResolver.ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
                        if (paramNames == null) {
                            ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                            if (pnd != null) {
                                paramNames = pnd.getParameterNames(candidate);
                            }
                        }
						// // 根据参数类型和参数名字获取对应的bean 对象
                        argsHolder = this.createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, this.getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                    } catch (UnsatisfiedDependencyException var27) {
                        if (this.logger.isTraceEnabled()) {
                            this.logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + var27);
                        }

                        if (causes == null) {
                            causes = new ArrayDeque(1);
                        }
						// 如果遍历过程中发现 没有在spring 容器中获取到bean 
						//  则会进行下异常的记录;如果遍历结束,还是没有找到相应的构造方法则 抛出异常;
                        causes.add(var27);
                        continue;
                    }
                } else {
                    if (parameterCount != explicitArgs.length) {
                        continue;
                    }

                    argsHolder = new ArgumentsHolder(explicitArgs);
                }
				// 参数个数相同的构造方法,则进行权重计算找到spring 认为更好的 构造方法去创建bean;
				// 分数越小越匹配;如果分数相同则记录下冲突
				// 如果分数相同,并且是严格模式则会报错;否则使用分数相同,但是最先遍历得到的构造方法;
                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();
                        ambiguousConstructors.add(constructorToUse);
                    }

                    ambiguousConstructors.add(candidate);
                }
            }
        }

        if (constructorToUse == null) {
            if (causes == null) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
            }

            UnsatisfiedDependencyException ex = (UnsatisfiedDependencyException)causes.removeLast();
            Iterator var34 = causes.iterator();

            while(var34.hasNext()) {
                Exception cause = (Exception)var34.next();
                this.beanFactory.onSuppressedException(cause);
            }

            throw ex;
        }
		
        if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousConstructors);
        }

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

    Assert.state(argsToUse != null, "Unresolved constructor arguments");
    // 传入构造方法和参数进行对象构建
    bw.setBeanInstance(this.instantiate(beanName, mbd, constructorToUse, argsToUse));
    return bw;
}

二、 推断构造方法使用总结:

2.1 只有一个构造方法(无参或者有参):

只有一个构造方法(无参或者有参是否有被@Autowired):直接使用这个构造方法;
此种需要分几种情况:

  • 只有一个默认的无参构造方法,则通过推断方法获取到的 构造方法数组是 null,此时直接使用无参构造方法创建对象;
  • 只有一个有参构造方法,不论该方法是否被@Autowired 标准也不论required = false/true,通过推断方法获取到的 构造方法数组只有这一个有参的构造方法,此时经过sort 排序后,然后进行遍历,因为只有一个有参的构造方法,所以遍历之后取得改有参构造方法完成对象创建;

2.2 有多个没有被@Autowired 标注的构造方法:

如果有多个构造方法,但是构造方法并没有被@Autowired 进行标注,则使用默认的无参构造方法,如果没有无参构造方法则报错;
此种情况,通过推断方法获取到的 构造方法数组是 null,此时直接使用无参构造方法创建对象,没有无参构造方法则报错;

2.3 有多个被@Autowired(required = false) 标注的构造方法:

如果有多个被 @Autowired(required = false)标注的构造方法,则进行排序,public 修饰的和入参多的在前面,然后一次遍历得到参数最多的构造方法;
此种需要分几种情况:

  • 如果没有默认的无参构造方法,则推断方法取到所有被@Autowired(required = false) 标注的构造方法,进行排序,然后进行遍历取的参数最多的构造方法;
  • 如果有默认的无参构造方法,则推断方法取到所有被@Autowired(required = false) 标注的和 默认无参的构造方法,进行排序,然后进行遍历取的参数最多的构造方法;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值