Spring源码系列(十三)Spring创建Bean的过程(三)

1.写在前面

上篇博客笔者主要讲了spring调用doCreateBean(beanName, mbdToUse, args);方法的前面的一小部分,后面还有许多的东西没有讲,今天笔者打算继续往后讲。废话不多说,直接开启今天的博客之旅吧。这篇博客篇幅过长,请读者耐心享用。

2.Spring中推断构造函数

上篇博客中讲到doCreateBean(beanName, mbdToUse, args);方法中的创建Bean的实例的方法createBeanInstance(beanName, mbd, args);具体的代码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.
    // 获取Bean的Class,这儿获取的A.Class,因为笔者条件断点的是a
	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
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}

    //通过工厂方法推断构造函数,同时创建对应的对象
	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) {
            // 这个参数只有在@Bean注解的方法的时候创建RootBeanDefinition的才会这个参数赋值,而@Bean注解的方法在上面
            // instantiateUsingFactoryMethod(beanName, mbd, args);已经创建完成返回了。
            // 所以这个判断只有在创建RootBeanDefinition的时候,同时它的工厂方法名为空,然后这个解析的工厂方法名不为空的时候,才会进入这个判断
            // 已经缓存的构造函数
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
                 // constructorArgumentsResolved默认为false
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
    //只有上面判断执行,这个判断才会执行,一般情况下不会执行
	if (resolved) {
		if (autowireNecessary) {
            //通过自动装配的构造函数方式实例化Bean
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
            //实例化Bean
			return instantiateBean(beanName, mbd);
		}
	}

	// Candidate constructors for autowiring?
    // 推断构造函数
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// Preferred constructors for default construction?
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}

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

上面的代码中间两个if的判断一般不会执行resolvedConstructorOrFactoryMethod目前只有在解析@Bean注解的时候,这个值才有值,而@Bean注解的方法,又会在instantiateUsingFactoryMethod(beanName, mbd, args);方法的时候,创建好了对应Bean,然后直接返回了。所以这个条件要满足的话,应该是自己创建对应RootBeanDefinition,然后对应的工厂方法名是为空,然后缓存的构造方法不为空,才会进中间的那几个if的判断。如果有其他用到的地方,目前笔者还是不知道的。如果有读者知道,可以告诉笔者,可能笔者后面继续看源码的时候,就可能会发现有的地方用到了这几个if的判断。目前没有发现。

开始今天的重点的方法determineConstructorsFromBeanPostProcessors(beanClass, beanName);,这个方法就是推断构造方法的,就是前面的两种方式创建Bean的条件都不满足的情况下。废话不多说,直接看代码,具体的代码如下:

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

    //这个判断是成立,不清楚的可以看下笔者的博客Spring源码系列(十一)Spring创建Bean的过程(一)
	if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
        //这儿取出来的是7个BeanPostProcessor(加了Aop的情况下)
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //实现这个SmartInstantiationAwareBeanPostProcessor的接口有三个ImportAwareBeanPostProcessor
            // AutowiredAnnotationBeanPostProcessor AnnotationAwareAspectJautoProxyCreator
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
				if (ctors != null) {
					return ctors;
				}
			}
		}
	}
	return null;
}

上面的判断是成立,看过笔者的Spring源码系列(十一)Spring创建Bean的过程(一)这篇博客,就知道这里判断为什么成立。以及有那7个BeanPostProcessor,同时其中有那几个实现SmartInstantiationAwareBeanPostProcessor接口的类,其中有三个,主要是ImportAwareBeanPostProcessorAutowiredAnnotationBeanPostProcessorAnnotationAwareAspectJautoProxyCreator然后会分别执行其中determineCandidateConstructors(beanClass, beanName);的方法。但是一个类中构造函数有很多种情况,于是笔者在下面的博客进行分类说明。

2.1默认的无参构造函数(没有加@Autowired)

第一种情况就是没有提供构造函数,就是一个默认的无参的函数,具体如下:

package com.ys.beanLife.bean;

import org.springframework.stereotype.Component;

@Component
public class A{
    public A(){}
}

假设Spring要创建A类的Bean,这个时候分别会去执行上面三个类的中的determineCandidateConstructors(beanClass, beanName);的方法。

第一次执行determineCandidateConstructors(beanClass, beanName);方法:ImportAwareBeanPostProcessor类,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
	return null;
}

可以发现这个类的这个方法的返回值就是null。所以可以直接跳过。

第二次执行determineCandidateConstructors(beanClass, beanName);方法:AnnotationAwareAspectJautoProxyCreator类,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) {
	return null;
}

可以发现这个类的这个方法的返回值就是null。所以可以直接跳过。

第三次执行determineCandidateConstructors(beanClass, beanName);方法:AutowiredAnnotationBeanPostProcessor类,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {

	// Let's check for lookup methods here...
    // 处理LookUp注解,不是本篇博客的重点
	if (!this.lookupMethodsChecked.contains(beanName)) {
		if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
			try {
				Class<?> targetClass = beanClass;
				do {
					ReflectionUtils.doWithLocalMethods(targetClass, method -> {
						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 ex) {
								throw new BeanCreationException(beanName,
										"Cannot apply @Lookup to beans without corresponding bean definition");
							}
						}
					});
					targetClass = targetClass.getSuperclass();
				}
				while (targetClass != null && targetClass != Object.class);

			}
			catch (IllegalStateException ex) {
				throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
			}
		}
		this.lookupMethodsChecked.add(beanName);
	}

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数,这个时候取出来应该是一个无参的构造函数
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,这儿也是为null
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //这儿获取的值也是空,不会进入这个判断
					if (ann != null) {
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
						boolean required = determineRequiredStatus(ann);
						if (required) {
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
							requiredConstructor = candidate;
						}
						candidates.add(candidate);
					}
                    //判断这个构造函数的参数的个数是不是等于0,这儿这个判断是成立的,给defaultConstructor赋了一个值
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //判断这个值是不是等于空,这儿这个集合等于空,这儿只有添加了@Autowired这个注解的时候,这个candidates才不为空
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
							candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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 = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这儿不满足
				else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //最后进入这个判断
				else {
                    //候选构造函数的值等于空的数组,
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //这个长度就是等于0,直接返回null
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,由于我们这儿是没有提供构造方法,默认的无参的。所以这些判断都是不会成立的。于是为判断这个构造函数的参数个数是不是等于0,如果是等于0,将这个构造函数存入到defaultConstructor变量中去。最后进行对应的五个判断,前四个判断都是不成立的,于是直接进入最后一个判断,创建一个空的构造器函数的数组对象,最后将这个数据存到candidateConstructorsCache变量中去,键是class,值是这个构造器函数的数组对象,最后判断这个数组的长度是不是大于0,如果大于0,返回这个数组,如果不大于0,直接返回null,所以这儿的结果是返回null。

总结:默认的构造无参构造函数(没有加@Autowired)的类,通过这个方法执行完后,返回的值是null

2.2有且只有一个构造函数(加了@Autowired)

第二种就是有且只有一个构造函数,我们这儿就提供一个默认无参的构造方法,并且这个方法加了@Autowired注解,具体的代码如下:

package com.ys.beanLife.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A{

    @Autowired()
    public A() {

    }
}

由于前面的两个的类的determineCandidateConstructors(beanClass, beanName);的方法都是返回null,所以我们直接看AutowiredAnnotationBeanPostProcessor类的determineCandidateConstructors(beanClass, beanName);的方法,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
    //省略处理LookUp注解的方法

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                //用来存加了@Autowired(required=true)注解的构造方法
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,这儿不是null
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                    //在这种情况下,返回的值就不是空
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //这儿获取的值不是空,直接进入这个判断
					if (ann != null) {
                        //这个值为空
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
                        //这儿的返回的值是true
						boolean required = determineRequiredStatus(ann);
						if (required) {
                            //这个时候这个candidates的长度也是空
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
                            //存入到这个变量中去
							requiredConstructor = candidate;
						}
                        //添加到candidates变量中去
						candidates.add(candidate);
					}
                    //由于上面的if执行了,所以这个else if不会执行
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //判断这个值是不是等于空,这儿这个值不为空
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.
                    //这个值不为空,所以这个判断是不会执行的
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
							candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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赋值
					candidateConstructors = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这儿不会执行
				else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //这个判断也不会进,因为前面的判断已经执行了
				else {              
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //这个长度就是等于1,直接返回刚才那个找到的构造函数
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,我们这儿提供的构造方法加了@Autowired的注解,所以这个判断会成立,然后去获取@Autowired注解中的required这个值等于多少,我们这儿提供的是true,所以将这个构造函数赋值给requiredConstructor变量。然后添加到添加到candidates集合中去。下面的五个判断,会直接进入第一个if判断,然后判断requiredConstructor的值是不是等于null,很明显这儿是不等于空的,于是往candidateConstructors赋值,最后再将这个变量put到candidateConstructorsCache,由于candidateConstructors这个变量的长度不等于0,所以返回的是这个默认的构造函数。

这个时候可能有读者会说,如果这个无参的构造函数上面的加的注解是@Autowired(required=false),那么结果是怎么样的呢?唯一的区别就是在下面的这个判断中的区别了,具体的代码如下:

if (ann != null) {
	if (requiredConstructor != null) {
		throw new BeanCreationException(beanName,
			"Invalid autowire-marked constructor: " + candidate +
			". Found constructor with 'required' Autowired annotation already: " +
			requiredConstructor);
	}
    //这个时候这个获取的值就是false
	boolean required = determineRequiredStatus(ann);
    //这个判断就不会进
	if (required) {
		if (!candidates.isEmpty()) {
			throw new BeanCreationException(beanName,
			"Invalid autowire-marked constructors: " + candidates +
			". Found constructor with 'required' Autowired annotation: " +
			candidate);
		}
        //这个值就不会存进去
		requiredConstructor = candidate;
	}
	candidates.add(candidate);
}

//判断这个值是不是等于空,这儿这个值不为空
if (!candidates.isEmpty()) {
	// Add default constructor to list of optional constructors, as fallback.
    //这个值为空。
	if (requiredConstructor == null) {
        //这个判断也是等于null
		if (defaultConstructor != null) {
			candidates.add(defaultConstructor);
		}
        //所以为执行这个判断,而且这个判断是成立的
		else if (candidates.size() == 1 && logger.isInfoEnabled()) {
			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赋值,这个还是会执行
	candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}

所以和加@Autowired的注解的区别没有多大的区别,无非就是requiredConstructor变量没有赋值,但是最终都是往candidateConstructors中赋值了,最后都是将这个put到candidateConstructorsCache这个Map中,最后返回的还是这个构造函数。

这个时候可能又有读者来说,如果这个构造函数有参数,你通读所有的代码你会发现和加没有加参数没有多大关系,所以也是会返回这个构造函数。

总结:有且只有一个构造函数,并且这个构造函数上加了@Autowired注解,而这个注解的required的值不管是true还是false,都是返回这个构造函数

2.3提供一个带参数的构造函数

上面说了一个构造函数的情况,一种是没有@Autowired注解的无参的构造函数,返回的null,另外一种是加了@Autowired注解的构造函数,不管构造函数的参数是多少,不管@Autowired中的required的值是多少,都会返回这个构造函数,那么一个构造函数,还有一种情况就是有参数的构造函数,但是这个构造函数没有加@Autowired的注解,具体的代码如下:

package com.ys.beanLife.bean;

import org.springframework.stereotype.Component;

@Component
public class A{
    
    public A(B b) {
    }
}

废话不多说还是直接上代码,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
    //省略处理LookUp注解的方法

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                //用来存加了@Autowired(required=true)注解的构造f方法
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,这儿是null
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                    
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //这儿获取的是空,直接跳过
					if (ann != null) {
                        
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
                      
						boolean required = determineRequiredStatus(ann);
						if (required) {
                           
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
                            
							requiredConstructor = candidate;
						}
                        
						candidates.add(candidate);
					}
                    //这个判断也是不会成立的
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //上面的判断没有进,这个判断也是不成立
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.               
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
							candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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 = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这个会执行,
                //将这个唯一带参的构造函数创建好对应数组存到candidateConstructors中去
				else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //这个判断也不会进,因为前面的判断已经执行了
				else {              
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //这个长度就是等于1,直接返回刚才那个找到的构造函数
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,我们这儿提供的一个有参的构造函数没有添加@Autowired的注解,所以第一个判断anno!=0,这个判断是不成立的,第二个判断,这个构造函数的参数的个数是等于0的,这个判断也是不成立的,于是会走下面的五个判断,只有第二个满足条件,于是创建Constructor数组将这个值存到candidateConstructors中,最后将这个值put到candidateConstructorsCache,最后判断这个candidateConstructorsCache的长度是不是大于0,如果大于0,直接返回这个candidateConstructorsCache,很明显这儿是满足条件,于是直接返回这个唯一的构造函数。

总结:提供了一个带参数的构造函数,同时这个构造函数上面没有添加@Autowired注解,这个时候返回的就是这个唯一的构造函数。

2.4多个构造函数(都没有添加@Autowired)

我们这儿提供多个构造函数,具体的例子如下:

package com.ys.beanLife.bean;

import org.springframework.stereotype.Component;

@Component
public class A{

    public A() {
    }

    public A(B b) {
    }

    public A(C c) {

    }
}

我们还是看原来的代码,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
    //省略处理LookUp注解的方法

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数
                    //这个时候取出来的构造函数如下:
                    //A()
                    //A(B b)
                    //A(C c)
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                //用来存加了@Autowired(required=true)注解的构造f方法
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数,下面的遍历只有是无参的构造函数会执行其中的代码,其他的时候都不会执行
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,这儿是null
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);   
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //这儿获取的是空,直接跳过
					if (ann != null) {
                        
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
                      
						boolean required = determineRequiredStatus(ann);
						if (required) {
                           
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
                            
							requiredConstructor = candidate;
						}
                        
						candidates.add(candidate);
					}
                    //这个判断会成立,只有在第一次遍历无参的构造函数的时候成立
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //上面的判断没有进,这个判断也是不成立
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.               
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
							candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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 = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这个判断也不会执行
                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //这个判断会执行,因为前面所有判断都没有执行,所以就创建了一个Constructor数组存入到candidateConstructors
				else {              
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //这个长度就是等于0,直接返回null
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,这个时候查找出来的是三个,分别是A()、A(B b)、A(C c),然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后判断这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,我们这儿提供了三个方法,这三个方法中,只有第一个无参的构造函数,才会执行for循环中的if判断的代码,将这个构造函数存到defaultConstructor变量中去,其他两个构造函数都是不会执行for循环中的if判断中的代码,最后再来看五个if的判断,只有最后一个if判断是成立的,所以这儿又是创建一个空的Constructor,最后将这个数组存到candidateConstructorsCache变量中去,最后这个candidateConstructorsCache变量的长度是等于0,所以返回的是null

可能有笔者会说这儿如果不提供无参的构造函数,会怎么样,无非就是就是defaultConstructor这个变量没有值,后面的操作还是一样的,返回的还是null

总结:多个构造函数,没有提供@Autowired注解,这个时候返回的就是null

2.5多个构造函数(只有一个构造函数加了@Autowired)

我们这个时候提供多个构造函数,只有一个构造函数上面提交@Autowired,具体的如下:

package com.ys.beanLife.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A{

    public A() {
    }

    @Autowired
    public A(B b) {
    }

    public A(C c) {

    }
}

我们来看原来的代码,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
    //省略处理LookUp注解的方法

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数
                    //这个时候取出来的构造函数如下:
                    //A()
                    //A(B b) 这个加了@Autowired注解
                    //A(C c)
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                //用来存加了@Autowired(required=true)注解的构造f方法
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数,下面的遍历会将默认的无参的构造方法存到defaultConstructor
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,这儿是第二个方法的时候不为空
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                    //在这种情况下,返回的值就不是空
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //第二个构造函数的时候不为空
					if (ann != null) {
                        
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
                      	//这儿获取的值是true
						boolean required = determineRequiredStatus(ann);
						if (required) {
                           
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
                            //将这个构造函数存到requiredConstructor
							requiredConstructor = candidate;
						}
                        //添加到candidates
						candidates.add(candidate);
					}
                    //这个判断会成立,只有在第一次遍历无参的构造函数的时候成立
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //这个判断是会进
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.               
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
                           		candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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
					candidateConstructors = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这个判断也不会执行
                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //这个判断也是不会执行
				else {              
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //这个长度就是等于1,直接返回找到的构造函数
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,这个时候查找出来的是三个,分别是A()、A(B b)这个加了@Autowired注解、A(C c),然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后判断这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,我们这儿提供了三个方法,这三个方法中,第一次进入循环的是无参的构造函数,就会直接存到defaultConstructor中去,第二次进入循环,正好这个方法加了@Autowired的注解,于是获取这个@Autowired注解中required的值等于多少,这个值是等于true,于是将这个构造函数存入到requiredConstructor最后将这个构造函数存入到candidates,第三次执行的时候,里面的判断都是不会进入,然后就会执行后面的五个判断,会进入第一个判断,这个时候判断的requiredConstructor的值是不等于null,所以直接将这个构造函数存到candidateConstructors,最后将candidateConstructors变量存入到candidateConstructorsCache,最后判断candidateConstructorsCache这个变量的长度是不是大于0,这儿的长度是1,所以直接返回这个构造函数。

可能有读者会说:如果这个加了@Autowired注解中required的值等于false情况是什么样的,这个时候区别就是获取的required的值等于false,这个时候就不会将这个构造函数存到requiredConstructor变量中去,然后还是会添加到candidates变量中去的,最后看的就是最后五个判断,只有第一个判断的会进,这个时候requiredConstructor的值等于null,于是将刚才找到的defaultConstructor添加到candidates变量中去,最后取出这个candidates集合中第一个的构造函数组存到candidateConstructors变量中去,最后将这个变量存到candidateConstructorsCache,最后判断这个变量长度是不是大于0,很明显这个长度是大于0,等于1,就直接返回这个加@Autowired的注解的构造函数和无参的构造函数。

总结:多个构造函数,只有一个构造函数上面加了@Autowired的注解,如果这个@Autowired注解中required的值等于true,就会返回这个加了@Autowired注解的构造函数。如果这个@Autowired注解中required的值等于false,并且这个@Autowired的注解没有加到无参的构造函数上,这个时候就会返回加了@Autowired注解的函数和无参的构造函数

2.6多个构造函数,都加了@Autowired,并且required的值等于true

如果多个构造函数,每个构造函数上面都加了@Autowired注解,并且这个@Autowired中的required的值都是true,具体的代码如下:

package com.ys.beanLife.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A{

    @Autowired
    public A() {
    }

    @Autowired
    public A(B b) {
    }

    @Autowired
    public A(C c) {

    }
}

我们来看原来的代码,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
    //省略处理LookUp注解的方法

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数
                    //这个时候取出来的构造函数如下:
                    //A() 这个加了@Autowired注解
                    //A(B b) 这个加了@Autowired注解
                    //A(C c) 这个加了@Autowired注解
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                //用来存加了@Autowired(required=true)注解的构造f方法
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数,下面的遍历会将默认的无参的构造方法存到defaultConstructor
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,不为空
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                    //在这种情况下,返回的值就不是空
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //不为空
					if (ann != null) {
                        //第一次不成立,第二次就成立了
						if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
                      	//这儿获取的值是true
						boolean required = determineRequiredStatus(ann);
						if (required) {
                           
							if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
                            //将这个构造函数存到requiredConstructor
							requiredConstructor = candidate;
						}
                        //添加到candidates
						candidates.add(candidate);
					}
                    //这个判断不会成立
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //这个判断不会进,上面已经报错了
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.               
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
                           		candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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
					candidateConstructors = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这个判断也不会执行
                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //这个判断也是不会执行
				else {              
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //上面已经报错,下面都不会执行
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,这个时候查找出来的是三个,分别是A()、A(B b)、A(C c),都是加了@Autowired注解,然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后判断这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,我们这儿提供了三个方法,这三个方法中,第一次进入循环的是无参的构造函数,这个方法加了@Autowired注解,而这个required的值是true,所以会存到requiredConstructor,然后第二次进入的循环的时候,这个时候@Autowired注解中的required的值也是true,于是会判断这个requiredConstructor这个值是不是等于null,如果等于null的话,就不会报错,但是这儿不等于null,就直接会抛出异常。

总结:多个构造函数,都加了@Autowired注解,并且这些注解中的required 的值是true的话,就直接会抛出异常,如果其中只有一个@Autowired(required=true)的话,也是会直接抛出异常。也就是说,除了所有的@Autowired(required=false)的情况下会不报错,其他组合多个@Autowired都会报错。

2.7多个构造函数,都加了@Autowired,并且required的值都是等于false

如果多个构造函数,每个构造函数上面都加了@Autowired注解,并且这个@Autowired中的required的值都是false,具体的代码如下:

package com.ys.beanLife.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A{

    @Autowired(required = false)
    public A() {
    }

    @Autowired(required = false)
    public A(B b) {
    }

    @Autowired(required = false)
    public A(C c) {

    }
}

我们来看原来的代码,具体的代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
    //省略处理LookUp注解的方法

	// Quick check on the concurrent map first, with minimal locking.
    // 这才是本篇博客的重点,去推断构造方法
    // 这儿取出来是空的,因为没有往其中put过
    // 候选的构造函数
	Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
            //这个时候又取了一次,怕有并发问题,类似于双重检查,这儿取出来应该也是空
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            //下面就开始推断构造函数了
			if (candidateConstructors == null) {
				Constructor<?>[] rawCandidates;
				try {
                    //从A类中取出所有的构造函数
                    //这个时候取出来的构造函数如下:
                    //A() 这个加了@Autowired(required=false)注解
                    //A(B b) 这个加了@Autowired(required=false)注解
                    //A(C c) 这个加了@Autowired(required=false)注解
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
				List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                //用来存加了@Autowired(required=true)注解的构造f方法
				Constructor<?> requiredConstructor = null;
                //默认的构造函数
				Constructor<?> defaultConstructor = null;
                //这个方法只对Kotlin有用,正常的情况直接返回null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                //不是合成的构造函数的个数
				int nonSyntheticConstructors = 0;
                //遍历所有的构造函数
				for (Constructor<?> candidate : rawCandidates) {
                    //如果这个构造函数不是合成的,就给nonSyntheticConstructors变量加1,至于什么是合成的函数,笔者前面的博客有讲过
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
                    //这个值默认为空,只有在是kotlin的情况可能不为空
					else if (primaryConstructor != null) {
						continue;
					}
                    //查找这个构造方法中有没有加@Autowired注解,不为空
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                    //在这种情况下,返回的值就不是空
					if (ann == null) {
                        //获取这个类的要使用的类,如果这个类是Cglib的代理的话,就返回的父类,如果没有直接返回对应的类,这儿获取的A.class
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        //只有是代理的情况下会执行
						if (userClass != beanClass) {
							try {
                                //根据当前遍历的构造函数,获取父类的对应的构造函数
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                //然后查找这个构造函数上是不是加了@Autowired注解
								ann = findAutowiredAnnotation(superCtor);
							}
							catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...
							}
						}
					}
                    //不为空
					if (ann != null) {
                        if (requiredConstructor != null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
                      	//这儿获取的值是false
						boolean required = determineRequiredStatus(ann);
						if (required) {
                            if (!candidates.isEmpty()) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
                            requiredConstructor = candidate;
						}
                        //添加到candidates
						candidates.add(candidate);
					}
                    //这个判断不会成立
					else if (candidate.getParameterCount() == 0) {
						defaultConstructor = candidate;
					}
				}
                //这个判断会进,requiredConstructor的值等于空
				if (!candidates.isEmpty()) {
					// Add default constructor to list of optional constructors, as fallback.               
					if (requiredConstructor == null) {
						if (defaultConstructor != null) {
                           		candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isInfoEnabled()) {
							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,这儿就是所有加了@Autowired(required=false)的构造函数
					candidateConstructors = candidates.toArray(new Constructor<?>[0]);
				}
                //找到所有的构造函数的长度等于1,同时这个构造函数的参数的长度大于0,这个判断也不会执行
                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
				}
                //非合成的构造函数的个数等于2,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //默认的构造函数的值不等于空,同时主要的构造函数不包含这个默认的构造函数,这个判断是不会成立的,直接跳过
				else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
						defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
				}
                //非合成的构造函数的个数等于1,同时primaryConstructor这个值不等于null,这个值只有在kotlin的情况,可能不为空
                //这个时候这个判断也不会成立
				else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
					candidateConstructors = new Constructor<?>[] {primaryConstructor};
				}
                //这个判断也是不会执行
				else {              
					candidateConstructors = new Constructor<?>[0];
				}
                //将这个候选构造函数的数组放入到候选构造函数的缓存中
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
    //这儿的长度大于0,返回的就是所有加了@Autowired(required=false)的构造函数
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

上面的代码走来获取的所有的构造函数然后存入到rawCandidates变量中去,这个时候查找出来的是三个,分别是A()、A(B b)、A(C c),都是加了@Autowired(required=false)注解,然后查找调用BeanUtils.findPrimaryConstructor(beanClass);方法查找主要的构造函数,这个方法只对kotlin的有用,所以默认情况下这个方法的返回值都是为空,所以primaryConstructor一般的情况下都是为空,然后开始遍历这些的构造函数,查找这些构造函数中不是合成的构造函数的个数,将这个个数存入到nonSyntheticConstructors变量中去,然后判断这些方法的上有没有添加@Autowired注解,如果这个类是cglib的代理的类,就查找它的父类的这个对应的构造方法上有没有添加@Autowired注解,我们这儿提供了三个方法,进入循环的时候,由于都是required的值等于false,所以都不会赋值给requiredConstructor,所以这儿就直接添加到candidates,最后将这个存入到candidateConstructors,最后将这个存入到candidateConstructorsCache,进行返回,也就是返回所有加@Autowired(required=false)的构造函数。

总结:多个构造函数,每个构造函数都加了@Autowired(required=false)的注解,这个时候返回的就是所有加了这个@Autowired(required=false)的构造函数。

3.推断构造方法总结

  1. 默认的无参的构造函数(没有加@Autowired注解),返回的是null。
  2. 有且只有一个构造函数(加了@Autowired注解),不管注解中的required的值是true还是false,都会返回这个构造函数。
  3. 提供一个带参数的构造函数,同时这个构造函数上面没有添加@Autowired注解,这个时候返回的就是这个唯一的构造函数。
  4. 多个构造函数,没有提供@Autowired注解,这个时候返回的就是null
  5. 多个构造函数(只有一个构造函数添加了@Autowired注解),如果这个@Autowired注解中required的值等于true,就会返回这个加了@Autowired注解的构造函数。如果这个@Autowired注解中required的值等于false,并且这个@Autowired的注解没有加到无参的构造函数上,这个时候就会返回加了@Autowired注解的函数和无参的构造函数。
  6. 多个构造函数,都加了@Autowired注解,并且这些注解中的required的值是true的话,就直接会抛出异常,如果其中只有一个@Autowired(required=true)的话,也是会直接抛出异常。也就是说,除了所有的@Autowired(required=false)的情况下会不报错,其他组合多个@Autowired都会报错。
  7. 多个构造函数,每个构造函数都加了@Autowired(required=false)的注解,这个时候返回的就是所有加了这个@Autowired(required=false)的构造函数。

4.写在最后

本篇博客,笔者就将Spring中整个推断构造方法给讲完了,后面还有一部分,整个Spring实例化Bean的过程就讲完了,注意,这个时候的实例化出来的Bean,属性还没有填充。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值