您好,登錄后才能下訂單哦!
這篇文章主要介紹了Spring Bean中Bean的實(shí)例化分析的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Spring Bean中Bean的實(shí)例化分析文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //省略無(wú)關(guān)代碼 try { // 這里就是我們分析的重點(diǎn)了 ?? Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //?? 注意這個(gè)邏輯:如果postProcessBeforeInstantiation方法返回非null 則將返回值作為創(chuàng)建的Bean。并中斷正常的創(chuàng)建流程 if (bean != null) { return bean; } } catch (Throwable ex) { //省略異常信息 } try { //真正創(chuàng)建Bean的邏輯 實(shí)例化Bean對(duì)象,為Bean屬性賦值等,這里暫不展開(kāi) Object beanInstance = doCreateBean(beanName, mbdToUse, args); //省略日志輸出 return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {//省略異常信息 }
resolveBeforeInstantiation
這個(gè)方法在BeanPostProcessor淺析 這一節(jié)分析過(guò)了 這里不再具體展開(kāi)了。
如果InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
方法返回null,那么將不會(huì)中斷正常Bean創(chuàng)建過(guò)程。
下面就來(lái)到的Bean實(shí)例化部分了。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //解析BeanClass,在BeanDefinition中類信息是以字符串形式展現(xiàn),這里解析到字符串后 會(huì)將其加載為Class 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()); } //如果設(shè)置了 Supplier 回調(diào),則使用給定的回調(diào)方法初始化策略,通過(guò)獲取Supplier#get得到實(shí)例化對(duì)象 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //如果工廠方法不為空,則使用工廠方法初始化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false; boolean autowireNecessary = false; if (args == null) { //加鎖 synchronized (mbd.constructorArgumentLock) { //條件成立 說(shuō)明構(gòu)造函數(shù)或FactoryMethod已經(jīng)被解析并被緩存,可直接利用構(gòu)造函數(shù)解析 //與后面的SimpleInstantiationStrategy#instantiate呼應(yīng) if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } //如果已經(jīng)被解析過(guò) if (resolved) { //條件成立 使用構(gòu)造函數(shù)注入 if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { //使用默認(rèn)構(gòu)造函數(shù)解析 return instantiateBean(beanName, mbd); } } // 使用SmartInstantiationAwareBeanPostProcessor 找到候選的構(gòu)造函數(shù) 用于注入 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // AutowireMode==AUTOWIRE_CONSTRUCTOR 條件成立 說(shuō)明使用基于構(gòu)造函數(shù)的注入方式 (默認(rèn)是AUTOWIRE_NO,需要?jiǎng)討B(tài)檢測(cè)) // mbd.hasConstructorArgumentValues() 條件成立 說(shuō)明構(gòu)造函數(shù)中擁有參數(shù) if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { //基于構(gòu)造函數(shù)自動(dòng)注入 return autowireConstructor(beanName, mbd, ctors, args); } // 如果mbd中配置了構(gòu)造函數(shù) 則使用它進(jìn)行注入 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // 使用默認(rèn)構(gòu)造函數(shù)實(shí)例化 return instantiateBean(beanName, mbd); }
上面將doCreateBean
精簡(jiǎn)一下,只暴露出我們比較關(guān)系的部分。一目了然,Bean的實(shí)例化過(guò)程就藏在createBeanInstance
方法中。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //解析BeanClass,在BeanDefinition中類信息是以字符串形式展現(xiàn),這里解析到字符串后 會(huì)將其加載為Class 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()); } //如果設(shè)置了 Supplier 回調(diào),則使用給定的回調(diào)方法初始化策略,通過(guò)獲取Supplier#get得到實(shí)例化對(duì)象 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //如果工廠方法不為空,則使用工廠方法初始化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false; boolean autowireNecessary = false; if (args == null) { //加鎖 synchronized (mbd.constructorArgumentLock) { //條件成立 說(shuō)明構(gòu)造函數(shù)或FactoryMethod已經(jīng)被解析并被緩存,可直接利用構(gòu)造函數(shù)解析 //與后面的SimpleInstantiationStrategy#instantiate呼應(yīng) if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } //如果已經(jīng)被解析過(guò) if (resolved) { //條件成立 使用構(gòu)造函數(shù)注入 if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { //使用默認(rèn)構(gòu)造函數(shù)解析 return instantiateBean(beanName, mbd); } } // 使用SmartInstantiationAwareBeanPostProcessor 找到候選的構(gòu)造函數(shù) 用于注入 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // AutowireMode==AUTOWIRE_CONSTRUCTOR 條件成立 說(shuō)明使用基于構(gòu)造函數(shù)的注入方式 (默認(rèn)是AUTOWIRE_NO,需要?jiǎng)討B(tài)檢測(cè)) // mbd.hasConstructorArgumentValues() 條件成立 說(shuō)明構(gòu)造函數(shù)中擁有參數(shù) if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { //基于構(gòu)造函數(shù)自動(dòng)注入 return autowireConstructor(beanName, mbd, ctors, args); } // 如果mbd中配置了構(gòu)造函數(shù) 則使用它進(jìn)行注入 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // 使用默認(rèn)構(gòu)造函數(shù)實(shí)例化 return instantiateBean(beanName, mbd); }
分析了上面的源碼之后,我們?cè)囍偨Y(jié)一下上面代碼主要完成的事情:
1、如果mbd配置了instanceSupplier回調(diào),則使用instanceSupplier去初始化BeanDefinition
2、如果mbd配置了工廠方法,則使用工廠方法區(qū)初始化BeanDefinition
3、實(shí)例化BeanDefinition
如果mbd已經(jīng)被解析過(guò)了,則根據(jù)緩存 選擇使用有參構(gòu)造函數(shù)注入還是默認(rèn)構(gòu)造函數(shù)注入
如果mbd沒(méi)有被解析過(guò),找到mbd中候選的構(gòu)造函數(shù)(一個(gè)類可能有多個(gè)構(gòu)造函數(shù)),再根據(jù)一些限定條件 選擇是基于有參構(gòu)造函數(shù)初始化還是默認(rèn)構(gòu)造函數(shù)初始化
針對(duì)第1點(diǎn),其實(shí)就是lambda8 supplier接口的使用,不再介紹。
針對(duì)第3點(diǎn),其實(shí)就是通過(guò)反射機(jī)制 創(chuàng)建實(shí)例對(duì)象,最終調(diào)用了SimpleInstantiationStrategy#instantiate
方法
針對(duì)第2點(diǎn) 舉例說(shuō)明下 工廠方法
與靜態(tài)工廠
生成Bean的兩種形式,再來(lái)展開(kāi)說(shuō)下instantiateUsingFactoryMethod
源碼。
配置Xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="peopleFactory" class="com.wojiushiwo.factorymethod.PeopleFactory"/> <!--實(shí)例方法--> <bean id="instanceMethod" factory-bean="peopleFactory" factory-method="createPeople"/> <!--靜態(tài)方法--> <bean id="staticFactoryMethod" class="com.wojiushiwo.factorymethod.People" factory-method="createPeople"/> </beans>
//實(shí)體對(duì)象 @Data public class People implements Serializable { private String name; private Integer age; public People() { } public static People createPeople() { People people = new People(); people.setAge(18); people.setName("我就是我"); return people; } } //People工廠類 public class PeopleFactory { public People createPeople() { return People.createPeople(); } } public class FactoryMethodDemo { public static void main(String[] args) { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("META-INF/spring.xml"); context.refresh(); People people = (People) context.getBean("staticFactoryMethod"); System.out.println(people); People people = (People) context.getBean("instanceMethod"); System.out.println(people); context.close(); } }
public BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); Object factoryBean; Class<?> factoryClass; boolean isStatic; //獲取FactoryBeanName,實(shí)例方法與靜態(tài)工廠方法的區(qū)別就在于有沒(méi)有FactoryBeanName String factoryBeanName = mbd.getFactoryBeanName(); if (factoryBeanName != null) { //如果存在FactoryBeanName,則說(shuō)明是實(shí)例方法 if (factoryBeanName.equals(beanName)) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition"); } //獲取當(dāng)前factoryBeanName名稱的Bean factoryBean = this.beanFactory.getBean(factoryBeanName); if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) { throw new ImplicitlyAppearedSingletonException(); } //獲取工廠類Class factoryClass = factoryBean.getClass(); //標(biāo)記為非靜態(tài) isStatic = false; } else { // 走到這里,說(shuō)明是靜態(tài)工廠方法 if (!mbd.hasBeanClass()) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "bean definition declares neither a bean class nor a factory-bean reference"); } //factoryBean設(shè)置為null factoryBean = null; //獲取工廠類Class,這里使用BeanDefinition作為其工廠類 factoryClass = mbd.getBeanClass(); //標(biāo)記為非靜態(tài) isStatic = true; } Method factoryMethodToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null; //explicitArgs 這個(gè)是getBean方法傳遞過(guò)來(lái)的,一般為null if (explicitArgs != null) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null; //加鎖 synchronized (mbd.constructorArgumentLock) { //獲取被解析的工廠方法 factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod; //條件成立 說(shuō)明工廠方法已經(jīng)被解析過(guò)了,并存到了mbd中緩存起來(lái)了 if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) { // Found a cached factory method... argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true); } } if (factoryMethodToUse == null || argsToUse == null) { //獲取工廠類 factoryClass = ClassUtils.getUserClass(factoryClass); //獲取類中的方法 Method[] rawCandidates = getCandidateMethods(factoryClass, mbd); List<Method> candidateList = new ArrayList<>(); for (Method candidate : rawCandidates) { //如果方法修飾符包含static,并且方法名稱是配置的FactoryMethod,則添加到候選集合中 if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) { candidateList.add(candidate); } } //如果候選集合有1個(gè)元素 并且BeanDefinition中未設(shè)置構(gòu)造參數(shù) (explicitArgs一般都為null ) if (candidateList.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) { //獲取方法 Method uniqueCandidate = candidateList.get(0); //如果方法參數(shù)為空 if (uniqueCandidate.getParameterCount() == 0) { mbd.factoryMethodToIntrospect = uniqueCandidate; synchronized (mbd.constructorArgumentLock) { //將下面這些全緩存到mbd中,下次直接用(與createBeanInstance方法呼應(yīng)上了) mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate; mbd.constructorArgumentsResolved = true; mbd.resolvedConstructorArguments = EMPTY_ARGS; } //實(shí)例化bd,設(shè)置到BeanWrapper中 bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS)); return bw; } } //程序走到這里 大概率是BeanDefinition中設(shè)置了構(gòu)造參數(shù) Method[] candidates = candidateList.toArray(new Method[0]); //按照修飾符及方法參數(shù) 進(jìn)行排序 AutowireUtils.sortFactoryMethods(candidates); ConstructorArgumentValues resolvedValues = null; //是否構(gòu)造函數(shù)注入 boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Method> ambiguousFactoryMethods = null; //最小參數(shù)數(shù)量 默認(rèn)是0 int minNrOfArgs; if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { //走到這里 說(shuō)明explicitArgs未被設(shè)置參數(shù) //如果bd設(shè)置了構(gòu)造參數(shù),則從bd中解析參數(shù) if (mbd.hasConstructorArgumentValues()) { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); //得到解析的最小參數(shù)數(shù)量 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } else { minNrOfArgs = 0; } } LinkedList<UnsatisfiedDependencyException> causes = null; //下面主要是推斷參數(shù)、FactoryMethod,代碼比較長(zhǎng) 就先不分析了 for (Method candidate : candidates) { Class<?>[] paramTypes = candidate.getParameterTypes(); if (paramTypes.length >= minNrOfArgs) { ArgumentsHolder argsHolder; if (explicitArgs != null) { // Explicit arguments given -> arguments length must match exactly. if (paramTypes.length != explicitArgs.length) { continue; } argsHolder = new ArgumentsHolder(explicitArgs); } else { // Resolved constructor arguments: type conversion and/or autowiring necessary. try { String[] paramNames = null; ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { paramNames = pnd.getParameterNames(candidate); } argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring, candidates.length == 1); } catch (UnsatisfiedDependencyException ex) { if (logger.isTraceEnabled()) { logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex); } // Swallow and try next overloaded factory method. if (causes == null) { causes = new LinkedList<>(); } causes.add(ex); continue; } } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // Choose this factory method if it represents the closest match. if (typeDiffWeight < minTypeDiffWeight) { factoryMethodToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousFactoryMethods = null; } // Find out about ambiguity: In case of the same type difference weight // for methods with the same number of parameters, collect such candidates // and eventually raise an ambiguity exception. // However, only perform that check in non-lenient constructor resolution mode, // and explicitly ignore overridden methods (with the same parameter signature). else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight && !mbd.isLenientConstructorResolution() && paramTypes.length == factoryMethodToUse.getParameterCount() && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) { if (ambiguousFactoryMethods == null) { ambiguousFactoryMethods = new LinkedHashSet<>(); ambiguousFactoryMethods.add(factoryMethodToUse); } ambiguousFactoryMethods.add(candidate); } } } if (factoryMethodToUse == null) { if (causes != null) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this.beanFactory.onSuppressedException(cause); } throw ex; } List<String> argTypes = new ArrayList<>(minNrOfArgs); if (explicitArgs != null) { for (Object arg : explicitArgs) { argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null"); } } else if (resolvedValues != null) { Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount()); valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values()); valueHolders.addAll(resolvedValues.getGenericArgumentValues()); for (ValueHolder value : valueHolders) { String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null")); argTypes.add(argType); } } String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes); //拋出異常 } else if (void.class == factoryMethodToUse.getReturnType()) { //拋出異常 } else if (ambiguousFactoryMethods != null) { //拋出異常 } if (explicitArgs == null && argsHolderToUse != null) { mbd.factoryMethodToIntrospect = factoryMethodToUse; argsHolderToUse.storeCache(mbd, factoryMethodToUse); } } Assert.state(argsToUse != null, "Unresolved factory method arguments"); //實(shí)例化bd 設(shè)置到BeanWrapper中 bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse)); return bw; }
至此經(jīng)過(guò)createBeanInstance
方法 就為我們創(chuàng)建了一個(gè)實(shí)例對(duì)象,但是現(xiàn)在這個(gè)對(duì)象屬性還未被賦值。
實(shí)例對(duì)象創(chuàng)建之后,就來(lái)到了對(duì)象屬性賦值過(guò)程了,我們大致看一下populateBean
方法,觀察下InstantiationAwareBeanPostProcessor
對(duì)屬性賦值過(guò)程的影響
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //省略無(wú)關(guān)代碼 boolean continueWithPropertyPopulation = true; //條件一 synthetic默認(rèn)值是false 一般都會(huì)成立 //條件二 成立的話 說(shuō)明存在InstantiationAwareBeanPostProcessor if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //在BeanPostProcessor淺析中分析到此方法時(shí)說(shuō)過(guò),若Bean實(shí)例化后回調(diào)不返回true 則對(duì)屬性賦值過(guò)程產(chǎn)生影響。以下代碼就是說(shuō)明 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } //ibp.postProcessAfterInstantiation=false時(shí) 屬性賦值過(guò)程終止 if (!continueWithPropertyPopulation) { return; }
關(guān)于“Spring Bean中Bean的實(shí)例化分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Spring Bean中Bean的實(shí)例化分析”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。