Spring?createBeanInstance實例化Bean
Spring實例Bean的方法
Spring實例Bean的方法,在AbstractAutowireCapableBeanFactory中的
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//解析Bean的類型,確認需要創(chuàng)建的bean實例的類可以實例化。
//如果沒有設(shè)置通過Class.forName獲取Bean類型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 確保class不為空,并且訪問權(quán)限是public
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方式創(chuàng)建Bean: 需要先有回調(diào)Bean
// 判斷當前beanDefinition中是否包含實例供應(yīng)器,此處相當于一個回調(diào)方法,利用回調(diào)方法來創(chuàng)建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//②FactoryMethod方式創(chuàng)建Bean: 需要在XML中配置factory-method
// 判斷是否有工廠方法,如果存在,會嘗試調(diào)用該Bean定義信息中的工廠方法來獲取實例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
//一個類可能有多個構(gòu)造器,所以Spring得根據(jù)參數(shù)個數(shù)、類型確定需要調(diào)用的構(gòu)造器,當多次構(gòu)建同一個 bean 時就不需要重新判斷應(yīng)該使用那種方式構(gòu)造Bean
boolean resolved = false;
//是否需要自動裝配
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 因為判斷過程會比較,所以spring會將解析、確定好的構(gòu)造函數(shù)緩存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
// 在下次創(chuàng)建相同時直接從RootBeanDefinition中的屬性resolvedConstructorOrFactoryMethod緩存的值獲取,避免再次解析,導(dǎo)致循環(huán)依賴
if (mbd.resolvedConstructorOrFactoryMethod != null) {
//標識以及解析過class的構(gòu)造器
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 有構(gòu)造參數(shù)的或者工廠
if (resolved) {
//已經(jīng)解析過class的構(gòu)造器,使用已經(jīng)解析好的構(gòu)造器
if (autowireNecessary) {
//構(gòu)造函數(shù)自動注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默認構(gòu)造器
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 從bean后置處理器中為自動裝配尋找構(gòu)造方法
// 以下情況符合其一即可進入
// 1、存在可選構(gòu)造方法
// 2、自動裝配模型為構(gòu)造函數(shù)自動裝配
// 3、給BeanDefinition中設(shè)置了構(gòu)造參數(shù)值
// 4、有參與構(gòu)造函數(shù)參數(shù)列表的參數(shù)
//一、確定構(gòu)造參數(shù)
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?
// 從bean后置處理器中為自動裝配尋找構(gòu)造方法, 有且僅有一個有參構(gòu)造或者有且僅有@Autowired注解構(gòu)造
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
// 構(gòu)造函數(shù)自動注入
// 二、有參構(gòu)造創(chuàng)建Bean
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 使用默認無參構(gòu)造函數(shù)創(chuàng)建對象,如果沒有無參構(gòu)造且存在多個有參構(gòu)造且沒有@AutoWired注解構(gòu)造,會報錯
//三、無參構(gòu)造創(chuàng)建Bean
return instantiateBean(beanName, mbd);
}
①:Supplier方式創(chuàng)建Bean:5、Spring源碼之Supplier
②:FactoryMethod方式創(chuàng)建Bean: 【Spring源碼】8.IOC之創(chuàng)建bean對象之FactoryMethod
③:自動裝配類型
- int AUTOWIRE_NO = 0;//表示沒有外部定義的自動裝配
- int AUTOWIRE_BY_NAME = 1;//通過名稱指示自動裝配bean屬性(適用于Bean所有屬性的setter)
- int AUTOWIRE_BY_TYPE = 2;//通過類型指示自動裝配bean屬性(適用于Bean所有屬性的setter)
- int AUTOWIRE_CONSTRUCTOR = 3;//構(gòu)造函數(shù)
- int AUTOWIRE_AUTODETECT = 4;//通過bean類的內(nèi)省確定適當?shù)淖詣友b配策略,在Spring3.0之后已經(jīng)不再支持。
- String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";//用于沒有代理的時候,也能強制返回實例
一、determineConstructorsFromBeanPostProcessors:確定構(gòu)造參數(shù)
實現(xiàn)父類SmartInstantiationAwareBeanPostProcessor后置處理器的determineCandidateConstructors方法
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;
//執(zhí)行后置處理器,確定構(gòu)造函數(shù)
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
這里會通過AutowiredAnnotationBeanPostProcessor后置處理器確定構(gòu)造函數(shù)
詳情:http://www.dbjr.com.cn/article/277330.htm
二、autowireConstructor:有參構(gòu)造創(chuàng)建Bean
創(chuàng)建構(gòu)造器解析器自動寫入構(gòu)造函數(shù)
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
//實例化BeanWrapper,是包裝bean的容器
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//如果getBean中傳入的參數(shù)不為空,那么就使用傳入的參數(shù)
if (explicitArgs != null) {
argsToUse = explicitArgs;
}//解析構(gòu)造參數(shù)
else {
Object[] argsToResolve = null;
//嘗試從緩存中獲取
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
//獲取緩存中的構(gòu)造器
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
//在緩存中找到了構(gòu)造器,就繼續(xù)從緩存中尋找緩存的構(gòu)造器參數(shù)
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//構(gòu)造器中沒有緩存的參數(shù),就需要獲取配置文件中配置的參數(shù)
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果有構(gòu)造器但是構(gòu)造器中沒有參數(shù),就需要解析構(gòu)造參數(shù)
if (argsToResolve != null) {
//解析參數(shù)類型,比如將配置的String類型轉(zhuǎn)換成int、boolean等類型
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
//如果沒有緩存,就需要先解析構(gòu)造函數(shù)
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// 如果傳入的構(gòu)造器數(shù)組不為空,就使用傳入的構(gòu)造器參數(shù),否則通過反射獲取class中定義的構(gòu)造器
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//通過反射獲取class中定義的構(gòu)造器
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);
}
}
//如果只有一個構(gòu)造函數(shù)并且參數(shù)值為null,則直接使用無參構(gòu)造器實例化
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.
//如果構(gòu)造器不會空或者需要構(gòu)造器注入則需要自動裝配
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//獲取構(gòu)造參數(shù)值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//2.1 解析參數(shù)并返回最小參數(shù)個數(shù)
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//給構(gòu)造函數(shù)排序,public構(gòu)造函數(shù)優(yōu)先、參數(shù)數(shù)量降序排序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
//如果找到已經(jīng)滿足的構(gòu)造器就直接返回
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;
}
//如果構(gòu)造器參數(shù)值小于最小參數(shù)個數(shù)直接返回
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
//獲取構(gòu)造器參數(shù)類型
Class<?>[] paramTypes = candidate.getParameterTypes();
//需要解析的參數(shù)值不為空
if (resolvedValues != null) {
try {
//通過構(gòu)造器上@ConstructorProperties注解獲取參數(shù)名稱
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
//如果參數(shù)名稱為空
if (paramNames == null) {
//獲取參數(shù)名稱解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//獲取參數(shù)名稱
paramNames = pnd.getParameterNames(candidate);
}
}
//根據(jù)獲取到的參數(shù)名和已經(jīng)查到的構(gòu)造參數(shù)和構(gòu)造參數(shù)類型來創(chuàng)建用戶創(chuàng)建構(gòu)造器用的構(gòu)造參數(shù)數(shù)組
//這個數(shù)組中包含了原始的參數(shù)列表和構(gòu)造后的參數(shù)列表,用來對比用
//2.2 創(chuàng)建構(gòu)造參數(shù)數(shù)組
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 (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//如果是寬松的構(gòu)造策略,則對比spring構(gòu)造的參數(shù)數(shù)組的類型和獲取到的構(gòu)造器參數(shù)的參數(shù)類型進行對比,返回不同的個數(shù)
//如果是嚴格的構(gòu)造策略,則檢查能否將構(gòu)造的參數(shù)數(shù)組賦值到構(gòu)造器參數(shù)的參數(shù)列表中
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 當前構(gòu)造函數(shù)最為匹配的話,清空先前ambiguousConstructors列表
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
//存在相同權(quán)重的構(gòu)造器,將構(gòu)造器添加到一個ambiguousConstructors列表變量中
//注意,這時候constructorToUse 指向的仍是第一個匹配的構(gòu)造函數(shù)
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
//如果沒有匹配的構(gòu)造函數(shù),拋出異常
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);
}
//緩存參數(shù)構(gòu)造器,下次創(chuàng)建直接使用
//并設(shè)置constructorArgumentsResolved為true,表示已經(jīng)解析過構(gòu)造函數(shù)
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
//2.3 實例化Bean
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
2.1 resolveConstructorArguments:解析參數(shù)并返回最小參數(shù)個數(shù)
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 是否有定制的類型轉(zhuǎn)換器,沒有的話直接使用BeanWrapper進行類型轉(zhuǎn)換
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 構(gòu)造一個BeanDefinitionValueResolver,專門用于解析constructor-arg中的value屬性,實際上還包括ref屬性,內(nèi)嵌bean標簽等等
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// minNrOfArgs 記錄執(zhí)行方法要求的最小參數(shù)個數(shù),一般情況下就是等于constructor-arg標簽指定的參數(shù)數(shù)量
int minNrOfArgs = cargs.getArgumentCount();
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);
}
// 假設(shè)A方法直接在配置文件中指定了index=3上要使用的參數(shù),那么這個時候A方法至少需要4個參數(shù)
// 但是其余的3個參數(shù)可能不是通過constructor-arg標簽指定的,而是直接自動注入進來的,那么在配置文件中我們就只配置了index=3上的參數(shù),也就是說 int minNrOfArgs = cargs.getArgumentCount()=1,這個時候 index=3,minNrOfArgs=1, 所以 minNrOfArgs = 3+1
if (index + 1 > minNrOfArgs) {
minNrOfArgs = index + 1;
}
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 如果已經(jīng)轉(zhuǎn)換過了,直接添加到resolvedValues集合中
if (valueHolder.isConverted()) {
resolvedValues.addIndexedArgumentValue(index, valueHolder);
}
else {
// 解析value/ref/內(nèi)嵌bean標簽等
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 將解析后的resolvedValue封裝成一個新的ValueHolder,
// 并將其source設(shè)置為解析constructor-arg得到的那個ValueHolder,
// 后期會用到這個屬性進行判斷
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
resolvedValueHolder.setSource(valueHolder);
resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
}
}
// 對getGenericArgumentValues進行解析
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;
}
2.2 createArgumentArray:創(chuàng)建構(gòu)造參數(shù)數(shù)組
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
// 嘗試找到匹配的構(gòu)造函數(shù)參數(shù)值,無論是索引的還是泛型的。
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
// 如果我們找不到直接匹配并且不應(yīng)該自動裝配,讓我們嘗試下一個通用的、無類型的參數(shù)值作為后備:它可以在類型轉(zhuǎn)換后匹配(例如,String -> int)。
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
// 我們找到了一個潛在的匹配 - 讓我們試一試。不要多次考慮相同的值定義!
usedValueHolders.add(valueHolder);
Object originalValue = valueHolder.getValue();
Object convertedValue;
if (valueHolder.isConverted()) {
convertedValue = valueHolder.getConvertedValue();
args.preparedArguments[paramIndex] = convertedValue;
}
else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
}
catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
args.resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
}
else {
// 這部分就是超出了參數(shù)定義,需要自動注入?yún)?shù)的處理
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
args.resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
return args;
}
2.3 instantiate:實例化Bean
private Object instantiate(String beanName, RootBeanDefinition mbd,
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
this.beanFactory.getAccessControlContext());
}
else {
//四、使用實例化策略創(chuàng)建Bean
return this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via factory method failed", ex);
}
}
三、instantiateBean:無參構(gòu)造創(chuàng)建Bean
無參構(gòu)造
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 使用默認的實例化策略來實例化對象,默認為 CglibSubclassingInstantiationStrategy 實現(xiàn),但是instantiate()方法只在SimpleInstantiationStrategy里有實現(xiàn)邏輯
//四、使用實例化策略創(chuàng)建Bean
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);
}
}
四、使用實例化策略創(chuàng)建Bean
這里會進入SimpleInstantiationStrategy的instantiate方法
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
//在將 XML 配置解析成 BeanDefinition 的時候,bean標簽的lookup-method和replaced-method會被分別解析成 LookupOverride 和 ReplaceOverride 對象
//添加到 BeanDefinition 的methodOverrides成員變量中
//如果沒有配置就會走當前這個流程
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;
});
}
//4.1、反射創(chuàng)建Bean
return BeanUtils.instantiateClass(ctor, args);
}
else {
//如果方法被覆蓋,通過Cglib實現(xiàn)代理類
//4.2、Cglib創(chuàng)建代理類
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
4.1、反射創(chuàng)建Bean
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
//設(shè)置訪問權(quán)限
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];
//初始化參數(shù)
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());
}
}
4.2、Cglib創(chuàng)建代理類
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
創(chuàng)建Cglib代理類
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
//創(chuàng)建Cglib增強子類
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
//4.1 反射創(chuàng)建Bean
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
//反射創(chuàng)建Bean
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
總結(jié)
自動構(gòu)造:autowireConstructor
- 將所有的候選構(gòu)造函數(shù)排序,排序規(guī)則[第一排序規(guī)則: public方法優(yōu)先,第二排序規(guī)則:參數(shù)數(shù)量降序]
- 設(shè)置一個算法,輸入構(gòu)造函數(shù),輸出一個整數(shù)
- 判斷構(gòu)造方法能否完成依賴注入,不能跳過該構(gòu)造函數(shù)
- 算法輸出的最小值則作為被選中的構(gòu)造函數(shù)
- 通過選中的構(gòu)造函數(shù)完成對象實例化
- 算法根據(jù)mbd.isLenientConstructorResolution(默認寬松模式)區(qū)分嚴格模式和寬松模式,不同的模式有不同計算方式
以上就是Spring createBeanInstance實例化Bean的詳細內(nèi)容,更多關(guān)于Spring createBeanInstance實例化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mybatis中oracle實現(xiàn)分頁效果實例代碼
實現(xiàn)分頁的方式有很多,但常用的是通過SQL來顯示分頁。這篇文章主要介紹了mybatis中oracle實現(xiàn)分頁效果實例代碼,有興趣的可以了解一下。2017-04-04
shiro與spring集成基礎(chǔ)Hello案例詳解
這篇文章主要介紹了shiro與spring集成基礎(chǔ)Hello案例詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
Mybatis Criteria使用and和or進行聯(lián)合條件查詢的操作方法
這篇文章主要介紹了Mybatis Criteria的and和or進行聯(lián)合條件查詢的方法,本文通過例子給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10
Java實現(xiàn)數(shù)據(jù)庫連接池的方法
這篇文章主要介紹了Java實現(xiàn)數(shù)據(jù)庫連接池的方法,涉及java數(shù)據(jù)庫連接池的創(chuàng)建、連接、刷新、關(guān)閉及狀態(tài)獲取的常用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07
Java線程狀態(tài)轉(zhuǎn)換關(guān)系實例解析
這篇文章主要介紹了Java線程狀態(tài)轉(zhuǎn)換關(guān)系實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08

