Spring?createBeanInstance實(shí)例化Bean
Spring實(shí)例Bean的方法
Spring實(shí)例Bean的方法,在AbstractAutowireCapableBeanFactory
中的
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. //解析Bean的類型,確認(rèn)需要創(chuàng)建的bean實(shí)例的類可以實(shí)例化。 //如果沒有設(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 // 判斷當(dāng)前beanDefinition中是否包含實(shí)例供應(yīng)器,此處相當(dā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定義信息中的工廠方法來獲取實(shí)例 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)造器,當(dāng)多次構(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) { //標(biāo)識以及解析過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 { //使用默認(rèn)構(gòu)造器 return instantiateBean(beanName, mbd); } } // Candidate constructors for autowiring? // 從bean后置處理器中為自動裝配尋找構(gòu)造方法 // 以下情況符合其一即可進(jìn)入 // 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. // 使用默認(rèn)無參構(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)省確定適當(dāng)?shù)淖詣友b配策略,在Spring3.0之后已經(jīng)不再支持。
- String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";//用于沒有代理的時候,也能強(qiáng)制返回實(shí)例
一、determineConstructorsFromBeanPostProcessors:確定構(gòu)造參數(shù)
實(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) { //實(shí)例化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)造器實(shí)例化 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ù)類型進(jìn)行對比,返回不同的個數(shù) //如果是嚴(yán)格的構(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. // 當(dāng)前構(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 實(shí)例化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進(jìn)行類型轉(zhuǎn)換 TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); // 構(gòu)造一個BeanDefinitionValueResolver,專門用于解析constructor-arg中的value屬性,實(shí)際上還包括ref屬性,內(nèi)嵌bean標(biāo)簽等等 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); // minNrOfArgs 記錄執(zhí)行方法要求的最小參數(shù)個數(shù),一般情況下就是等于constructor-arg標(biāo)簽指定的參數(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標(biāo)簽指定的,而是直接自動注入進(jìn)來的,那么在配置文件中我們就只配置了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標(biāo)簽等 Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); // 將解析后的resolvedValue封裝成一個新的ValueHolder, // 并將其source設(shè)置為解析constructor-arg得到的那個ValueHolder, // 后期會用到這個屬性進(jìn)行判斷 ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); } } // 對getGenericArgumentValues進(jìn)行解析 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:實(shí)例化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 { //四、使用實(shí)例化策略創(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 { // 使用默認(rèn)的實(shí)例化策略來實(shí)例化對象,默認(rèn)為 CglibSubclassingInstantiationStrategy 實(shí)現(xiàn),但是instantiate()方法只在SimpleInstantiationStrategy里有實(shí)現(xiàn)邏輯 //四、使用實(shí)例化策略創(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); } }
四、使用實(shí)例化策略創(chuàng)建Bean
這里會進(jìn)入SimpleInstantiationStrategy的instantiate方法
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, final Constructor<?> ctor, Object... args) { //在將 XML 配置解析成 BeanDefinition 的時候,bean標(biāo)簽的lookup-method和replaced-method會被分別解析成 LookupOverride 和 ReplaceOverride 對象 //添加到 BeanDefinition 的methodOverrides成員變量中 //如果沒有配置就會走當(dāng)前這個流程 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實(shí)現(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增強(qiáng)子類 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ù)完成對象實(shí)例化
- 算法根據(jù)mbd.isLenientConstructorResolution(默認(rèn)寬松模式)區(qū)分嚴(yán)格模式和寬松模式,不同的模式有不同計算方式
以上就是Spring createBeanInstance實(shí)例化Bean的詳細(xì)內(nèi)容,更多關(guān)于Spring createBeanInstance實(shí)例化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mybatis中oracle實(shí)現(xiàn)分頁效果實(shí)例代碼
實(shí)現(xiàn)分頁的方式有很多,但常用的是通過SQL來顯示分頁。這篇文章主要介紹了mybatis中oracle實(shí)現(xiàn)分頁效果實(shí)例代碼,有興趣的可以了解一下。2017-04-04實(shí)例解析Java關(guān)于static的作用
只要是有學(xué)過Java的都一定知道static,也一定能多多少少說出一些作用和注意事項。文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04shiro與spring集成基礎(chǔ)Hello案例詳解
這篇文章主要介紹了shiro與spring集成基礎(chǔ)Hello案例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11Mybatis Criteria使用and和or進(jìn)行聯(lián)合條件查詢的操作方法
這篇文章主要介紹了Mybatis Criteria的and和or進(jìn)行聯(lián)合條件查詢的方法,本文通過例子給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10Java實(shí)現(xiàn)數(shù)據(jù)庫連接池的方法
這篇文章主要介紹了Java實(shí)現(xiàn)數(shù)據(jù)庫連接池的方法,涉及java數(shù)據(jù)庫連接池的創(chuàng)建、連接、刷新、關(guān)閉及狀態(tài)獲取的常用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07Java8 Zip 壓縮與解壓縮的實(shí)現(xiàn)
這篇文章主要介紹了Java8 Zip 壓縮與解壓縮的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Java線程狀態(tài)轉(zhuǎn)換關(guān)系實(shí)例解析
這篇文章主要介紹了Java線程狀態(tài)轉(zhuǎn)換關(guān)系實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08