【Spring源代码阅读之九】调用getBean()时,determineConstructors推断构造autowireConstructor或instantiateBean实例化Bean

导图(关注红色部分)

在这里插入图片描述

AbstractAutowireCapableBeanFactory#createBeanInstance

/**
 * 使用适当的实例化策略为指定bean创建新实例:
 * 工厂方法、@Autowaired构造函数或默认无参构造实例化。
 */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.
	/**
	 * 获得Class
	 */
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	/**
	 * 确保类是可访问的
	 * 默认情况下,即使是private修饰的类,Spring也是允许访问的,
	 * 因为{@link AbstractBeanDefinition#isNonPublicAccessAllowed()}默认返回true
	 */
	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接口,则调用该接口的get()方法返回实例
	 * JDK8新特性,支持函数式创建对象,Supplier接口中只有一个get()方法
	 * 	比如:Supplier<User> sup= User::new;//此时并不会调用对象的构造方法,即不会创建对象
	 * 	sup.get() //此时会调用对象的构造方法,即获得到真正对象,且每次都会调用构造方法,即每次获得的对象不同
	 */
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}

	/**
	 * BeanDefinition中是否存在工厂方法名称,存在则利用名称对应的方法产生对象
	 * 	1、可在XML模式下通过如下方式指定
	 * 		<bean factory-method="xxx"></bean>
	 * 	2、在注解模式下@Bean注解的方法是静态时
	 */
	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	/**
	 * 以下为利用构造方法创建实例
	 */
	/**
	 * 这个是一个标识,标识BeanDefinition可以使用指定的方式构建对象,不再推断对象的构建方式
	 * 初始化为false,Spring会优先认为推断构建方式
	 */
	boolean resolved = false;
	/**
	 * 标识BeanDefinition构建的实例是否自动装配
	 * 默认为false,不自动装配
	 */
	boolean autowireNecessary = false;
	/**
	 * 只有当没有参数参与实例的构建且存在指定的构建方式,才更改如上标识
	 * 当原型模式的Bean在多次构建时,不用多次走推断了,这里的resolved和
	 * constructorArgumentsResolved在第一次推断构建方式后被设置的
	 */
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	/**
	 * 为true的情况下走指定的构建方式创建实例,并根据是否自动装配走不同的方式
	 */
	if (resolved) {
		if (autowireNecessary) {
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			return instantiateBean(beanName, mbd);
		}
	}

	// Candidate constructors for autowiring?
	/**
	 * 获取可选的构造(使用的是BeanPostProcessor)
	 * 可选的是指有且仅有一个有参构造 或者 有且仅有一个@Autowired注解构造
	 */
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	/**
	 * 以下条件符合其一即可进入
	 * 	1、存在可选构造
	 * 	2、自动装配模型为构造函数自动装配
	 * 	3、给BeanDefinition中设置了构造参数值
	 * 	4、有参与构造函数参数列表的参数
	 */
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// No special handling: simply use no-arg constructor.
	/**
	 * 使用无参构造函数创建对象
	 * 注意:没有无参构造且存在多个有参构造且没有@Autowired注解构造,会报错
	 */
	return instantiateBean(beanName, mbd);
}

determineConstructorsFromBeanPostProcessors

/**
 * 确定用于给定bean的候选构造函数,使用Bean的后置处理器机制
 * @see AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors(java.lang.Class, java.lang.String)
 */
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
		throws BeansException {

	if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
				if (ctors != null) {
					return ctors;
				}
			}
		}
	}
	return null;
}

AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

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

	// Let's check for lookup methods here..
	/**
	 * 处理含有@Lookup注解的方法
	 * 如果集合中没有BeanName,则走一遍Bean中所有的方法,过滤是否含有Lookup方法
	 */
	if (!this.lookupMethodsChecked.contains(beanName)) {
		try {
			/**
			 * 在方法中循环过滤所有的方法
			 */
			ReflectionUtils.doWithMethods(beanClass, method -> {
				/**
				 * 获取method上的@Lookup注解
				 */
				Lookup lookup = method.getAnnotation(Lookup.class);
				/**
				 * 存在此注解的话,就将方法和注解中的内容构建LookupOverride对象,设置进BeanDefinition中
				 */
				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");
					}
				}
			});
		}
		catch (IllegalStateException ex) {
			throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
		}
		/**
		 * 无论对象中是否含有@Lookup方法,过滤完成后都会放到集合中,证明此Bean已经检查完@Lookup注解了
		 */
		this.lookupMethodsChecked.add(beanName);
	}

	// Quick check on the concurrent map first, with minimal locking.
	/**
	 * 从缓存中拿构造函数,不存在的话就进入代码块中再拿一遍,还不存在的话就进行下方的逻辑
	 * 同时这个参数是最终返回的
	 * 这里是双重检查
	 */
	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;
				/**
				 * 获取Bean中所有的构造函数
				 */
				try {
					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;
				/**
				 * 获取主构造函数(在Klion语言中存在),下方关于这个变量不再解释,不研究
				 */
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
				/**
				 * 标识,表示不是合成构造函数的数量
				 * 合成构造函数 -> 有方法参数并对实例进行赋值的构造函数
				 */
				int nonSyntheticConstructors = 0;
				/**
				 * 遍历所有的构造函数
				 */
				for (Constructor<?> candidate : rawCandidates) {
					/**
					 * 构造函数不是合成构造函数,标识累加
					 * @see assist.IsSynthetic#main(java.lang.String[])
					 */
					if (!candidate.isSynthetic()) {
						nonSyntheticConstructors++;
					}
					/**
					 * 忽略
					 */
					else if (primaryConstructor != null) {
						continue;
					}
					/**
					 * 查找构造函数上{@link Autowired}注解的属性
					 * 断点应该还判断{@link Value}的属性,但是此注解不能注释在构造函数上,暂时不理解
					 */
					AnnotationAttributes ann = findAutowiredAnnotation(candidate);
					/**
					 * 注解不存在,则再通过方法获取用户类,如果是用户类则返回用户类,还判断了CGLIB情况,
					 * CGLIB情况则返回目标类,然后获取参数一致的构造函数再获取注解
					 */
					if (ann == null) {
						Class<?> userClass = ClassUtils.getUserClass(beanClass);
						if (userClass != beanClass) {
							try {
								Constructor<?> superCtor =
										userClass.getDeclaredConstructor(candidate.getParameterTypes());
								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);
						}
						/**
						 * 获取@Autowired注解中required属性的值
						 */
						boolean required = determineRequiredStatus(ann);
						/**
						 * 为true则将这个构造函数设置为带有依赖项的构造函数
						 * 并进行一个判断,不可存在多个带有依赖项的构造函数
						 */
						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;
					}
				}

				/**
				 * 存在@Autowired注解的函数,并且required值为false,则此注解不起作用
				 * 但是存在默认构造函数,则将默认构造函数添加进集合中
				 * 并将集合变为数组使用
				 */
				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.isWarnEnabled()) {
							logger.warn("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]);
				}
				/**
				 * 如果只存在一个构造函数,且这个构造函数有参数列表,则使用这个构造函数
				 */
				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);
			}
		}
	}
	/**
	 * 使用构造列表中没有值,则返回null
	 */
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

autowireConstructor

protected BeanWrapper autowireConstructor(
		String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

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

ConstructorResolver#autowireConstructor

/**
 * “自动连线构造函数”(按类型具有构造函数参数)行为。如果指定了显式构造函数参数值,
 * 则也会应用此方法,将所有剩余参数与bean工厂中的bean匹配。
 * <p>这与构造函数注入相对应:在这种模式下,Spring bean工厂能够托管期望基于构造函数的依赖解析的组件。
 */
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
		@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

	/**
	 * 构建Bean实例包装对象
	 */
	BeanWrapperImpl bw = new BeanWrapperImpl();
	/**
	 * 给包装对象设置一些属性
	 */
	this.beanFactory.initBeanWrapper(bw);

	/**
	 * Spring对这个Bean进行实例化使用的构造函数
	 */
	Constructor<?> constructorToUse = null;
	/**
	 * Spring执行构造函数使用的参数封装类
	 */
	ArgumentsHolder argsHolderToUse = null;
	/**
	 * 参与构造函数实例化过程的参数
	 */
	Object[] argsToUse = null;

	/**
	 * 如果传入了参,则使用传入的参数
	 */
	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	/**
	 * 没有传入参数的话就走else
	 */
	else {
		Object[] argsToResolve = null;
		synchronized (mbd.constructorArgumentLock) {
			/**
			 * 获取BeanDefinition中解析完成的构造函数
			 */
			constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
			/**
			 * BeanDefinition中存在构造函数并且存在构造函数的参数,赋值进行使用
			 */
			if (constructorToUse != null && mbd.constructorArgumentsResolved) {
				// Found a cached constructor...
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		/**
		 * BeanDefinition中存在缓存的构造函数参数,解析成为参与构造函数实例化的参数
		 */
		if (argsToResolve != null) {
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
		}
	}

	/**
	 * BeanDefinition中没有解析完成的构造函数,则需要解析
	 */
	if (constructorToUse == null) {
		// Need to resolve the constructor.
		/**
		 * 一个标识,以下有一个情况成立即为true
		 * 		1、传进来构造函数,证明spring根据之前代码的判断,知道应该使用哪个构造函数
		 * 		2、BeanDefinition中设置为构造函数注入模型
		 */
		boolean autowiring = (chosenCtors != null ||
				mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		ConstructorArgumentValues resolvedValues = null;

		/**
		 * 定义一个变量,意思是构造函数的最小参数个数
		 * 这是一个推断值,Spring并不确定即将使用的构造函数有多少个参数
		 */
		int minNrOfArgs;
		/**
		 * 如果传入了参与构造函数实例化的参数值,那么参数的数量即为最小参数个数
		 */
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		/**
		 * 否则进入else
		 */
		else {
			/**
			 * 获取BeanDefinition中存放的参与构造函数参数的值
			 * 这个值可能通过后置处理器或{@link ImportBeanDefinitionRegistrar}设置
			 * @see mbd.getConstructorArgumentValues().addGenericArgumentValue()
			 */
			ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
			/**
			 * 实例化构造函数参数值存放实例
			 */
			resolvedValues = new ConstructorArgumentValues();
			/**
			 * 确定最小参数个数
			 * 如果BeanDefinition没有设置构造函数参数,这里返回零
			 */
			minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
		}

		// Take specified constructors, if any.
		/**
		 * 获取Spring能够明确推断使用的构造函数
		 */
		Constructor<?>[] candidates = chosenCtors;
		/**
		 * Spring并不能够确定的话,就从Class中获取全部的构造函数
		 */
		if (candidates == null) {
			Class<?> beanClass = mbd.getBeanClass();
			try {
				candidates = (mbd.isNonPublicAccessAllowed() ?
						beanClass.getDeclaredConstructors() : beanClass.getConstructors());
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Resolution of declared constructors on bean Class [" + beanClass.getName() +
						"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
			}
		}
		/**
		 * 对候选的构造函数进行排序,先是访问权限后是参数个数,大致如下
		 * 		public权限参数数量由多到少
		 * 		参数列表相同则	protected权限在前,private权限在后
		 * 		最后是默认权限(不加修饰符)
		 *
		 * 例如:
		 * 	public XXX(Object o1, Object o2, Object o3)
		 * 	public XXX(Object o1, Object o2)
		 * 	public XXX(Object o1)
		 * 	protected XXX(String s1, Object o2, Object o3)
		 * 	private XXX(Integer s1, Object o2, Object o3)
		 * 	protected XXX(String s1, Object o2)
		 * 	private XXX(Integer s1, Object o2)
		 * 	XXX(String s1)
		 */
		AutowireUtils.sortConstructors(candidates);
		/**
		 * 定义一个差异变量,这个变量很重要,变量的大小决定着构造函数是否能够被使用
		 */
		int minTypeDiffWeight = Integer.MAX_VALUE;
		/**
		 * 不明确的构造函数集合,正常情况下差异量不可能相同
		 */
		Set<Constructor<?>> ambiguousConstructors = null;
		LinkedList<UnsatisfiedDependencyException> causes = null;

		/**
		 * 循环候选的构造函数
		 */
		for (Constructor<?> candidate : candidates) {
			/**
			 * 获取构造函数的参数类型列表
			 */
			Class<?>[] paramTypes = candidate.getParameterTypes();

			/**
			 * 由于之前已经对构造函数进行了排序
			 * 已经确定使用哪个构造函数了并且参与的参数大于构造函数的参数数量,
			 * 再往后遍历的话,构造函数的参数列表数量越来越小,权限越来越小,越不符合了
			 * 所以直接不再遍历了
			 */
			if (constructorToUse != null && argsToUse.length > paramTypes.length) {
				// Already found greedy constructor that can be satisfied ->
				// do not look any further, there are only less greedy constructors left.
				break;
			}
			/**
			 * 如果本构造函数的参数列表数量小于要求的最小数量,显然不符合,遍历下一个
			 */
			if (paramTypes.length < minNrOfArgs) {
				continue;
			}

			/**
			 * 存放构造函数解析完成的参数列表
			 */
			ArgumentsHolder argsHolder;
			/**
			 * 存在需要解析的构造函数参数
			 */
			if (resolvedValues != null) {
				try {
					/**
					 * 获取构造函数上的{@link ConstructorProperties}注解中的参数
					 */
					String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
					/**
					 * 没有上面那个注解,则获取构造函数参数列表中属性的名称
					 */
					if (paramNames == null) {
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
						if (pnd != null) {
							paramNames = pnd.getParameterNames(candidate);
						}
					}
					/**
					 * 对构造函数依赖项进行解析,其中就是调用BeanFactory的resolveDependency进行解析
					 * 有兴趣的朋友可以深入阅读以下,本人只是大概过了一下,里面代码较复杂,没有深入研究
					 */
					argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
							getUserDeclaredConstructor(candidate), autowiring);
				}
				catch (UnsatisfiedDependencyException ex) {
					if (logger.isTraceEnabled()) {
						logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
					}
					// Swallow and try next constructor.
					if (causes == null) {
						causes = new LinkedList<>();
					}
					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 constructor if it represents the closest match.
			/**
			 * 本次的构造函数差异值小于上一个构造函数,则进行构造函数更换
			 */
			if (typeDiffWeight < minTypeDiffWeight) {
				/**
				 * 将确定使用的构造函数设置为本构造
				 */
				constructorToUse = candidate;
				/**
				 * 更换使用的构造函数参数封装类
				 */
				argsHolderToUse = argsHolder;
				/**
				 * 更换参与构造函数实例化的参数
				 */
				argsToUse = argsHolder.arguments;
				/**
				 * 差异值更换
				 */
				minTypeDiffWeight = typeDiffWeight;
				/**
				 * 不明确的构造函数列表清空为null
				 */
				ambiguousConstructors = null;
			}
			/**
			 * 差异值相等,则表明构造函数不正常,放入异常集合
			 * 注意:如果在之后的遍历中,找到了更合适的构造函数时,这个集合参数会被置为空
			 * 		之后会根据这个集合判断是否抛异常
			 */
			else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
				if (ambiguousConstructors == null) {
					ambiguousConstructors = new LinkedHashSet<>();
					ambiguousConstructors.add(constructorToUse);
				}
				ambiguousConstructors.add(candidate);
			}
		}

		/**
		 * 以下两种情况会抛异常
		 *  1、至此为止还没有确定使用的构造函数
		 * 	2、存在模棱两可的构造函数并且不允许存在模棱两可的构造函数
		 */
		if (constructorToUse == null) {
			if (causes != null) {
				UnsatisfiedDependencyException ex = causes.removeLast();
				for (Exception cause : causes) {
					this.beanFactory.onSuppressedException(cause);
				}
				throw ex;
			}
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Could not resolve matching constructor " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
		}
		else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Ambiguous constructor matches found in bean '" + beanName + "' " +
					"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
					ambiguousConstructors);
		}

		/**
		 * 没有传入参与构造函数参数列表的参数时,对构造函数缓存到BeanDefinition中
		 * 	1、缓存BeanDefinition进行实例化时使用的构造函数
		 * 	2、缓存BeanDefinition代表的Bean的构造函数已解析完标识
		 * 	3、缓存参与构造函数参数列表值的参数列表
		 */
		if (explicitArgs == null) {
			argsHolderToUse.storeCache(mbd, constructorToUse);
		}
	}

	try {
		/**
		 * 获取创建bean实例的实例化策略
		 */
		final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
		Object beanInstance;

		/**
		 * Java安全管理器不说明
		 * 根据策略进行实例的创建
		 * @see SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.reflect.Constructor, java.lang.Object...)
		 */
		if (System.getSecurityManager() != null) {
			final Constructor<?> ctorToUse = constructorToUse;
			final Object[] argumentsToUse = argsToUse;
			beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
					beanFactory.getAccessControlContext());
		}
		else {
			beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
		}

		/**
		 * 将实例填入包装类的属性中
		 */
		bw.setBeanInstance(beanInstance);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean instantiation via constructor failed", ex);
	}
}

resolveConstructorArguments

/**
 * 将BeanDefinition中的构造函数参数解析为resolvedValues对象。这可能需要查找其他Bean
 * <p>此方法还用于处理静态工厂方法的调用。
 */
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
		ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

	TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
	TypeConverter converter = (customConverter != null ? customConverter : bw);
	BeanDefinitionValueResolver valueResolver =
			new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);

	/**
	 * BeanDefinition中的参数的个数为最低参数个数
	 */
	int minNrOfArgs = cargs.getArgumentCount();

	/**
	 * 遍历BeanDefinition中的Map参数集合
	 */
	for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
		/**
		 * 获取参数的坐标
		 */
		int index = entry.getKey();
		if (index < 0) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Invalid constructor argument index: " + index);
		}
		/**
		 * 如果坐标大于参数个数,则参数个数+1
		 * 这里并不直接将坐标设置为参数个数,是遍历中存在一个大于参数个数的坐标
		 * 就证明多一个参数,不必直接赋值
		 */
		if (index > minNrOfArgs) {
			minNrOfArgs = index + 1;
		}
		ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
		/**
		 * 参数值是否需要转换
		 * 不转换则直接给参数Holder
		 * 否则转换后再给
		 */
		if (valueHolder.isConverted()) {
			resolvedValues.addIndexedArgumentValue(index, valueHolder);
		}
		else {
			Object resolvedValue =
					valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
			ConstructorArgumentValues.ValueHolder resolvedValueHolder =
					new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
			resolvedValueHolder.setSource(valueHolder);
			resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
		}
	}

	/**
	 * 遍历List集合,逻辑和遍历Map集合一样,不需要转换的直接给定,否则转换后给定
	 */
	for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
		if (valueHolder.isConverted()) {
			resolvedValues.addGenericArgumentValue(valueHolder);
		}
		else {
			Object resolvedValue =
					valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
			ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
					resolvedValue, valueHolder.getType(), valueHolder.getName());
			resolvedValueHolder.setSource(valueHolder);
			resolvedValues.addGenericArgumentValue(resolvedValueHolder);
		}
	}

	return minNrOfArgs;
}
SimpleInstantiationStrategy#instantiate
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
		final Constructor<?> ctor, @Nullable Object... args) {

	/**
	 * 判断BeanDefinition中是否有需要重写的方法(例如@Lookup注解的方法)
	 * 没有的话直接使用构造函数进行实例化
	 * 否则会使用CGLIB代理进行实例化
	 */
	if (!bd.hasMethodOverrides()) {
		if (System.getSecurityManager() != null) {
			// use own privileged to change accessibility (when security is on)
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(ctor);
				return null;
			});
		}
		return (args != null ? BeanUtils.instantiateClass(ctor, args) : BeanUtils.instantiateClass(ctor));
	}
	else {
		/**
		 * 这里的代码就不一一列举了,对CGLIB有了解或知道@Configuration中的@Bean方法实例化过程的,这里的代码会理解的
		 * 想看源码的活可以下载源码或下载Maven仓库中的源码阅读
		 * 无非就是对需要重写的方法加入Filter拦截
		 * @see CglibSubclassingInstantiationStrategy#instantiateWithMethodInjection(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.reflect.Constructor, java.lang.Object...)
		 */
		return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
	}
}

instantiateBean

/**
 * 使用默认的构造函数进行实例化,并组建包装对象
 */
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
	try {
		Object beanInstance;
		final BeanFactory parent = this;
		/**
		 * @see SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
		 */
		if (System.getSecurityManager() != null) {
			beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					getInstantiationStrategy().instantiate(mbd, beanName, parent),
					getAccessControlContext());
		}
		else {
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
		}
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}
SimpleInstantiationStrategy#instantiate
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
	// Don't override the class with CGLIB if no overrides.
	/**
	 * 没有需要重写的方法,就不使用CGLIB
	 */
	if (!bd.hasMethodOverrides()) {
		Constructor<?> constructorToUse;
		synchronized (bd.constructorArgumentLock) {
			/**
			 * 获得BeanDefinition中缓存的构造
			 */
			constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
			/**
			 * 为null则从Class中获取构造,并缓存到BeanDefinition中
			 */
			if (constructorToUse == null) {
				final Class<?> clazz = bd.getBeanClass();
				if (clazz.isInterface()) {
					throw new BeanInstantiationException(clazz, "Specified class is an interface");
				}
				try {
					if (System.getSecurityManager() != null) {
						constructorToUse = AccessController.doPrivileged(
								(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
					}
					else {
						constructorToUse = clazz.getDeclaredConstructor();
					}
					bd.resolvedConstructorOrFactoryMethod = constructorToUse;
				}
				catch (Throwable ex) {
					throw new BeanInstantiationException(clazz, "No default constructor found", ex);
				}
			}
		}
		/**
		 * 利用构造实例
		 */
		return BeanUtils.instantiateClass(constructorToUse);
	}
	/**
	 * 到这里就是存在需要重写的方法,通过CGLIB代理实现,实际使用两个Callback拦截方法,从容器中获取实现
	 * 例如:@Lookup注解的方法
	 * @see CglibSubclassingInstantiationStrategy#instantiateWithMethodInjection(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
	 */
	else {
		// Must generate CGLIB subclass.
		return instantiateWithMethodInjection(bd, beanName, owner);
	}
}
BeanUtils#instantiateClass
/**
 * 使用构造函数newInstance实例化Bean
 */
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
	Assert.notNull(ctor, "Constructor must not be null");
	try {
		ReflectionUtils.makeAccessible(ctor);
		return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
				KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
	}
	catch (InstantiationException ex) {
		throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
	}
	catch (IllegalAccessException ex) {
		throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
	}
	catch (IllegalArgumentException ex) {
		throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
	}
	catch (InvocationTargetException ex) {
		throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
	}
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值