构造函数的选取逻辑
- 在doCreateBean中给属性赋值之前,调用createBeanInstance
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// factoryBeanInstanceCache存储的是:beanName对应的FactoryBean实例对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根据构造函数实例化,创建Bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
- 进入createBeanInstance,整体逻辑的描述如源码中注释,构造函数的返回主要是通过自动注入autowireConstructor和使用默认构造函数instantiateBean,重点关注determineConstructorsFromBeanPostProcessors,它里面的逻辑主要是调用SmartInstantiationAwareBeanPostProcessor类型的后置处理器,determineCandidateConstructors方法返回候选的构造器集合,源码接着下一步
// Make sure bean class is actually resolved at this point.
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());
}
// Spring5新增的判断逻辑
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) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析,则直接从从缓存中获取
if (resolved) {
if (autowireNecessary) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 使用默认构造函数构造
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);
}
// Spring5新增
// 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);
- determineConstructorsFromBeanPostProcessors的源码
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
- AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法,分为两步:一、检查@Lookup注解;二、执行真正的构造器选择逻辑
// Let's check for lookup methods here...
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.
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 {
// 获取所有声明的构造器
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);
// 存放required=true的构造器
Constructor<?> requiredConstructor = null;
// 存放默认的构造器
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 查找当前构造器上面的注解
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
// 没有注解
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) {
// 说明已经存在required=true的构造器,抛异常
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
// 判断注解的属性required的值
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.add(candidate);
}
else if (candidate.getParameterCount() == 0) {
// 如果当前构造器上面没有注解,并且参数个数为0,则存入默认构造器defaultConstructor
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
// 没有required=true的构造器
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]);
}
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
// 如果适用的构造器只有1个,并且参数的个数大于0,则直接选用该构造器
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
// 如果有2个构造器,并且默认的构造器不为空
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);
-
对上述第二步的流程做一个说明,
- 首先对候选的构造器结果candidateConstructors作双重检查,以防多线程并发带来的问题;
- 接着通过Class<?>反射获取所有声明的构造函数
-
对上述通过反射获取的构造函数循环遍历
- 对于每个构造器,判断上面是否包含@Autowired,@Value,javax.inject.Inject等注解
- 如果当前构造器上面没有注解,并且参数个数为0,则存入默认构造器defaultConstructor
- 如果有注解,并且存放required=true的构造器不为空,则抛异常;如果为空,判断注解的属性required的值,把当前构造器存入requiredConstructor
- 结果判断:没有required=true的构造器,并且默认构造器不为空,则存入最终适用的构造器
- 如果适用的构造器只有1个,并且参数的个数大于0,则直接选用该构造器
- 如果有2个构造器,并且默认的构造器不为空,也存入最终适用的构造器
- 如果构造器只有一个,并且primaryConstructor不为空,则直接存入结果构造器集合
- 以上都不符合,则返回空,在推出该函数后,如果为空,则系统最后会采用默认的构造函数
- 把结果存入缓存,便于下一次直接获取
- 举例说明:
- 如果只有一个@Autowired注解,且required默认,即:值为true,则Spring会采用被注解标注的那一个
@Autowired
public Color(Blue blue, Cyan cyan) {
this.blue = blue;
this.cyan = cyan;
}
public Color(Cyan cyan) {
this.cyan = cyan;
}
// 默认构造函数
public Color() {}
- 如果有多个被@Autowired标注的构造函数,两个required都是true,Spring会抛异常
// ----------------------------示例代码----------------------------
@Autowired
public Color(Blue blue, Cyan cyan) {
this.blue = blue;
this.cyan = cyan;
}
@Autowired
public Color(Cyan cyan) {
this.cyan = cyan;
}
// 默认构造函数
public Color() {}
}
- 如果有多个被@Autowired标注的构造函数,一个required是true,一个required是false
- 情形(一),抛异常:“Found constructor with 'required' Autowired annotation already XXX”
// ----------------------------示例代码----------------------------
@Autowired(required = false)
public Color(Blue blue, Cyan cyan) {
this.blue = blue;
this.cyan = cyan;
}
@Autowired
public Color(Cyan cyan) {
this.cyan = cyan;
}
// 默认构造函数
public Color() {}
- 情形(二),也会抛异常:“Found constructor with 'required' Autowired annotation:”
// ----------------------------示例代码----------------------------
@Autowired
public Color(Blue blue, Cyan cyan) {
this.blue = blue;
this.cyan = cyan;
}
@Autowired(required = false)
public Color(Cyan cyan) {
this.cyan = cyan;
}
// 默认构造函数
public Color() {}
- 如果有多个被@Autowired标注的构造函数,两个required都是false,Spring经过处理之后会根据选取的原则选择一个构造函数,结果candidates会存入下面示例代码中所有的构造函数,返回出去之后,外层函数会调用autowireConstructor,选择一个构造函数,源码分析如下:
// ----------------------------示例代码----------------------------
@Autowired(required = false)
public Color(Blue blue, Cyan cyan) {
this.blue = blue;
this.cyan = cyan;
}
@Autowired(required = false)
public Color(Cyan cyan) {
this.cyan = cyan;
}
// 默认构造函数
public Color() {}
// ---------------上述情形的源码判断逻辑---------------
if (ann != null) {
if (requiredConstructor != null) {
// 说明已经存在required=true的构造器,抛异常
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
// 判断注解的属性required的值
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.add(candidate);
}
- AbstractAutowireCapableBeanFactory的autowireConstructor源码
new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs)
- ConstructResolver的autowireConstructor方法,流程比较长,总的逻辑是:先选取待使用的构造函数(选取的原则是:构造函数排序,public优先且按参数数量降序,非public按参数数量降序),把构造的实例加入BeanWrapper中,根据实例化策略、构造函数以及构造函数参数实例化Bean(实例化逻辑调用在instantiate方法,源码接着后面。)
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// explicitArgs通过getBean方法传入,如果不为空,则直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
} else {
// 如果在getBean方法没有指定,则尝试从配置文件中解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 从缓存中获取
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果缓存中存在
if (argsToResolve != null) {
// 解析参数类型,如:给定构造函数是(int, int),通过此方法后("1", "1")会被解析为(1, 1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
// 没有被缓存
if (constructorToUse == null || argsToUse == null) {
// Spring5更改逻辑顺序,Spring4此段逻辑在[2.]之后
// 1.Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
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);
}
}
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 2. Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} else {
// 提取配置文件中配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 用于承接解析后的构造函数参数值
resolvedValues = new ConstructorArgumentValues();
// 能解析到的构造函数参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
/**
* 根据构造函数参数锁定对应的构造函数,根据参数个数匹配,在匹配之前需要完成排序
*/
// 构造函数排序,public优先且按参数数量降序,非public按参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
// 由于构造函数已经按照规则排过序,当已经找到了满足该条件的一个构造函数,会进入到此逻辑
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
// 配置文件中配置构造函数:1.通过指定参数位置索引创建;2.指定参数名称设定参数值
if (resolvedValues != null) {
try {
// 从注解中获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
// 根据参数名称和类型创建ArgumentsHolder
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
} 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 ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
} else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != 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;
ambiguousConstructors = null;
} else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
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);
}
if (explicitArgs == null && argsHolderToUse != null) {
// 把解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 把构造的实例加入BeanWrapper中:根据实例化策略、构造函数以及构造函数参数实例化Bean
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
- ConstructResolver的instantiate
try {
InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
this.beanFactory.getAccessControlContext());
}
else {
// 策略默认是SimpleInstantiationStrategy
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
- SimpleInstantiationStrategy的instantiate
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 BeanUtils.instantiateClass(ctor, args);
}
else {
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
- BeanUtils#instantiateClass,实例化class的最后一步,先对基本数据类型转换为默认值,最后通过反射实例化
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
return ctor.newInstance(argsWithDefaultValues);
}
}
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());
}