Spring中Autowired原理

1. 构造方法参数Autowire

  • BeanClass可以在构造方法上标注@Autowired注解,Spring在创建Bean实例时将自动为其注入依赖参数;
  • Spring会优先使用标注@Autowired注解的构造方法;
  • 当一个构造方法标注了@Autowired注解且required=true时,其余构造方法不允许再标注@Autowired注解;
  • 当多个构造方法标注了@Autowired注解且required=false时,它们会成为候选者,Spring将选择具有最多依赖项的构造方法;
  • 如果没有候选者可以满足,Spring将使用默认的无参构造方法(如果存在);
  • 如果Class有多个含参构造方法,且都没有标注@Autowired注解,此时在创建Bean时会抛错。

1.1. Spring创建Bean实例

创建Bean实例在AbstractAutowireCapableBeanFactory类的createBeanInstance方法:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
   
	// Make sure bean class is actually resolved at this point.
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	// public和access判断,略

	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
   
		return obtainFromSupplier(instanceSupplier, beanName);
	}

	// 使用工厂创建Bean实例,@Bean注解标注的方法会使用这种方式创建Bean实例
	// 后续有章节进行分析
	if (mbd.getFactoryMethodName() != null) {
   
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
   
		synchronized (mbd.constructorArgumentLock) {
   
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
   
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	if (resolved) {
   
		if (autowireNecessary) {
   
			return autowireConstructor(beanName, mbd, null, null);
		} else {
   
			return instantiateBean(beanName, mbd);
		}
	}

	// 获取候选的构造方法
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   
		// 使用构造方法创建Bean实例
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// 此处通过RootBeanDefinition获取候选的构造方法然后创建Bean实例,和上面基本一致
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
   
		return autowireConstructor(beanName, mbd, ctors, null);
	}

	// 使用默认构造方法创建Bean实例
	return instantiateBean(beanName, mbd);
}

1.2. 获取候选的构造方法集

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

	// Let's check for lookup methods here...
	// 略

	// 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;
				try {
   
					// 使用java反射获取声明了的所有构造方法
					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;
				// null
				Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
				int nonSyntheticConstructors = 0;
				for (Constructor<?> candidate : rawCandidates) {
   
					if (!candidate.isSynthetic()) {
   
						nonSyntheticConstructors++;
					} else if (primaryConstructor != null) {
   
						continue;
					}
					// 在构造方法上查找@Autowired注解
					MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
					if (ann != null) {
   
						// 如果之前已经找到了requiredConstructor则抛错
						if (requiredConstructor != null) {
   
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
						boolean required = determineRequiredStatus(ann);
						// 构造方法标注@Autowired注解且required=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集
						candidates.add(candidate);
					} else if (candidate.getParameterCount() == 0) {
   
						defaultConstructor = candidate;
					}
				}
				if (!candidates.isEmpty()) {
   
					// 把默认无参构造方法添加到candidates集
					if (requiredConstructor == null) {
   
						if (defaultConstructor != null) {
   
							candidates.add(defaultConstructor);
						}
					}
					candidateConstructors = candidates.toArray(new Constructor<?>[0]);
				} else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
   
					// 当candidates为空时,即所有构造方法都没有标注@Autowired注解
					// 且只有一个构造方法时,默认使用这个构造方法
					candidateConstructors = new Constructor<?>[] {
   rawCandidates[0]};
				} else {
   
					candidateConstructors = new Constructor<?>[0];
				}
				// 维护缓存
				this.candidateConstructorsCache.put(beanClass, candidateConstructors);
			}
		}
	}
	return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

1.3. 使用构造方法创建Bean实例

autowireConstructor(beanName, mbd, ctors, args);

autowireConstructor方法:

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

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

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
		Constructor<?>[] chosenCtors, Object[] explicitArgs) {
   

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

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

	// explicitArgs == null
	if (explicitArgs != null) {
   
		argsToUse = explicitArgs;
	} else {
   
		Object[] argsToResolve = null;
		// 获取mbd中缓存的构造方法和参数并用其创建对象,此处不详细分析
		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 = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
		}
	}

	// 这里从候选构造方法集选择一个最佳构造方法
	if (constructorToUse == null || argsToUse == null) {
   
		Constructor<?>[] candidates = chosenCtors;
		if (candidates == null) {
   
			// 使用反射获取声明的所有构造方法
		}

		// 只有一个无参的默认构造方法
		// 1. 将其放入mbd缓存起来
		// 2. 使用这个构造方法创建Bean实例并返回
		if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
   
			Constructor
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.D.Chuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值