第二次調用Bean後置處理器:第一次推斷構造方法
第二次調用Bean後置處理器調用鏈
createBeanInstance:1210, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:558, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$Lambda$12)
getSingleton:229, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:326, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:200, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:854, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:889, AbstractApplicationContext (org.springframework.context.support)
refresh:553, AbstractApplicationContext (org.springframework.context.support)
main:9, AnnotationConfigApplication (com.tbryant.springtest.demo)
第二次調用Bean後置處理器入口
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 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());
}
// 通過Supplier表達式拿對象,一般爲null
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果有工廠方法,那麼就調用工廠方法,不需要spring實例化
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?
// 第二次調用後置處理器 入口,推斷構造方法
// 有且進有一個帶參構造方法的情況下不爲null
// 有多個@Autowired(required = false)的構造方法的情況下不爲null
// 其他情況都爲空
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);
}
ConfigurationClassPostProcessor.determineCandidateConstructors
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here...
// 處理@Lookup start
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, 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");
}
}
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
this.lookupMethodsChecked.add(beanName);
}
// 處理@Lookup end
// Quick check on the concurrent map first, with minimal locking.
// 從緩存中拿當前類型對應的構造方法,第一次肯定是null
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;
// 處理Kotlin類,如果是Java類永遠返回null
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
// 非合併構造方法個數,對於Java類沒什麼用,Kotlin類可能有多個候選構造方法
int nonSyntheticConstructors = 0;
// 遍歷所有構造方法
for (Constructor<?> candidate : rawCandidates) {
// 不是合成的構造方法
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
// 不會進
else if (primaryConstructor != null) {
continue;
}
// 取@Autowired屬性
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
// userClass:CGLib的目標類型
// 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);
}
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,spring認爲是默認構造方法
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 有@Autowired註解的構造方法纔會進
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]);
}
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// Java類不會進
else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
// Java類不會進
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);
}
這個方法返回構造方法數組,以下兩種情況返回值不爲null
- 有且僅有一個帶參構造方法,返回那個構造方法
- 有多個@Autowired(required = false)註解的構造方法,返回這些構造方法
@Autowired(required = true)含義:使用此構造方法
@Autowired(required = false)含義:將此構造方法設置爲自動裝配候選構造方法
第二次推斷構造方法
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 最終使用的構造函數
Constructor<?> constructorToUse = null;
// 最終使用的構造函數參數(封裝)
ArgumentsHolder argsHolderToUse = null;
// 最終使用的構造函數參數
Object[] argsToUse = null;
// explicitArgs 通常爲空,解析構造函數參數
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
// 找出來的參數,並不是最終使用構造函數的參數
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) {
// 參數轉換,比如給的是string使用的是對象
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// 沒解析過
if (constructorToUse == null || argsToUse == null) {
// 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;
}
}
// Need to resolve the constructor.
// 是否需要解析構造方法
boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
// 臨時存放構造方法參數
ConstructorArgumentValues resolvedValues = null;
// 最小參數數量
int minNrOfArgs;
// explicitArgs 通常爲空
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 拿程序員手動傳的參數值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 計算構造方法最小參數數量
// 把手動配置的構造函數參數放到resolvedValues
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 排序 先public 再參數個數,個數多的優先級高
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 != 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 {
// 保存參數名字
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
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 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;
ambiguousConstructors = null;
}
// 如果有一個候選構造方法 && 權重值相等,這兩個構造方法都屬於模糊不清的構造方法,spring不知道用哪個
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");
// 通過推斷出來的構造函數反射實例化對象
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
手動裝配
沒有顯式提供構造方法:使用默認構造方法
提供一個構造方法:使用該構造方法
提供多個構造方法,包含默認構造方法:使用默認構造方法
提供多個構造方法,不包含默認構造方法:報錯
提供多個構造方法,有一個@Autowired(required = true)的構造方法:使用有@Autowired(required = true)的構造方法
提供多個構造方法,有多個@Autowired(required = true)的構造方法:報錯
提供多個構造方法,有一個@Autowired(required = true)的構造方法和多個@Autowired(required = false)的構造方法:報錯
提供多個構造方法,有多個@Autowired(required = false)的構造方法:使用符合條件的&參數最多的構造方法
使用構造方法自動裝配
使用符合條件的&參數最多的構造方法