日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

解析属性注入规则

發(fā)布時(shí)間:2024/4/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 解析属性注入规则 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

當(dāng)容器在對(duì)屬性進(jìn)行依賴注入時(shí),如果發(fā)現(xiàn)屬性值需要進(jìn)行類(lèi)型轉(zhuǎn)換,如屬性值是容器中另一個(gè)Bean實(shí)例對(duì)象的引用,則容器首先需要根據(jù)屬性值解析出所引用的對(duì)象,然后才能將該引用對(duì)象注入到目標(biāo)實(shí)例對(duì)象的屬性上去,對(duì)屬性進(jìn)行解析的由resolveValueIfNecessary()方法實(shí)現(xiàn),其源碼如下:

//解析屬性值,對(duì)注入類(lèi)型進(jìn)行轉(zhuǎn)換 @Nullable public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {// We must check each value to see whether it requires a runtime reference// to another bean to be resolved.//對(duì)引用類(lèi)型的屬性進(jìn)行解析if (value instanceof RuntimeBeanReference) {RuntimeBeanReference ref = (RuntimeBeanReference) value;//調(diào)用引用類(lèi)型屬性的解析方法return resolveReference(argName, ref);}//對(duì)屬性值是引用容器中另一個(gè)Bean名稱(chēng)的解析else if (value instanceof RuntimeBeanNameReference) {String refName = ((RuntimeBeanNameReference) value).getBeanName();refName = String.valueOf(doEvaluate(refName));//從容器中獲取指定名稱(chēng)的Beanif (!this.beanFactory.containsBean(refName)) {throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);}return refName;}//對(duì)Bean類(lèi)型屬性的解析,主要是Bean中的內(nèi)部類(lèi)else if (value instanceof BeanDefinitionHolder) {// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());}else if (value instanceof BeanDefinition) {// Resolve plain BeanDefinition, without contained name: use dummy name.BeanDefinition bd = (BeanDefinition) value;String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +ObjectUtils.getIdentityHexString(bd);return resolveInnerBean(argName, innerBeanName, bd);}//對(duì)集合數(shù)組類(lèi)型的屬性解析else if (value instanceof ManagedArray) {// May need to resolve contained runtime references.ManagedArray array = (ManagedArray) value;//獲取數(shù)組的類(lèi)型Class<?> elementType = array.resolvedElementType;if (elementType == null) {//獲取數(shù)組元素的類(lèi)型String elementTypeName = array.getElementTypeName();if (StringUtils.hasText(elementTypeName)) {try {//使用反射機(jī)制創(chuàng)建指定類(lèi)型的對(duì)象elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());array.resolvedElementType = elementType;}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error resolving array type for " + argName, ex);}}//沒(méi)有獲取到數(shù)組的類(lèi)型,也沒(méi)有獲取到數(shù)組元素的類(lèi)型//則直接設(shè)置數(shù)組的類(lèi)型為Objectelse {elementType = Object.class;}}//創(chuàng)建指定類(lèi)型的數(shù)組return resolveManagedArray(argName, (List<?>) value, elementType);}//解析list類(lèi)型的屬性值else if (value instanceof ManagedList) {// May need to resolve contained runtime references.return resolveManagedList(argName, (List<?>) value);}//解析set類(lèi)型的屬性值else if (value instanceof ManagedSet) {// May need to resolve contained runtime references.return resolveManagedSet(argName, (Set<?>) value);}//解析map類(lèi)型的屬性值else if (value instanceof ManagedMap) {// May need to resolve contained runtime references.return resolveManagedMap(argName, (Map<?, ?>) value);}//解析props類(lèi)型的屬性值,props其實(shí)就是key和value均為字符串的mapelse if (value instanceof ManagedProperties) {Properties original = (Properties) value;//創(chuàng)建一個(gè)拷貝,用于作為解析后的返回值Properties copy = new Properties();original.forEach((propKey, propValue) -> {if (propKey instanceof TypedStringValue) {propKey = evaluate((TypedStringValue) propKey);}if (propValue instanceof TypedStringValue) {propValue = evaluate((TypedStringValue) propValue);}if (propKey == null || propValue == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error converting Properties key/value pair for " + argName + ": resolved to null");}copy.put(propKey, propValue);});return copy;}//解析字符串類(lèi)型的屬性值else if (value instanceof TypedStringValue) {// Convert value to target type here.TypedStringValue typedStringValue = (TypedStringValue) value;Object valueObject = evaluate(typedStringValue);try {//獲取屬性的目標(biāo)類(lèi)型Class<?> resolvedTargetType = resolveTargetType(typedStringValue);if (resolvedTargetType != null) {//對(duì)目標(biāo)類(lèi)型的屬性進(jìn)行解析,遞歸調(diào)用return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);}//沒(méi)有獲取到屬性的目標(biāo)對(duì)象,則按Object類(lèi)型返回else {return valueObject;}}catch (Throwable ex) {// Improve the message by showing the context.throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Error converting typed String value for " + argName, ex);}}else if (value instanceof NullBean) {return null;}else {return evaluate(value);} } //解析引用類(lèi)型的屬性值 @Nullable private Object resolveReference(Object argName, RuntimeBeanReference ref) {try {Object bean;//獲取引用的Bean名稱(chēng)String refName = ref.getBeanName();refName = String.valueOf(doEvaluate(refName));//如果引用的對(duì)象在父類(lèi)容器中,則從父類(lèi)容器中獲取指定的引用對(duì)象if (ref.isToParent()) {if (this.beanFactory.getParentBeanFactory() == null) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Can't resolve reference to bean '" + refName +"' in parent factory: no parent factory available");}bean = this.beanFactory.getParentBeanFactory().getBean(refName);}//從當(dāng)前的容器中獲取指定的引用Bean對(duì)象,如果指定的Bean沒(méi)有被實(shí)例化//則會(huì)遞歸觸發(fā)引用Bean的初始化和依賴注入else {bean = this.beanFactory.getBean(refName);//將當(dāng)前實(shí)例化對(duì)象的依賴引用對(duì)象this.beanFactory.registerDependentBean(refName, this.beanName);}if (bean instanceof NullBean) {bean = null;}return bean;}catch (BeansException ex) {throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);} } //解析array類(lèi)型的屬性 private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {//創(chuàng)建一個(gè)指定類(lèi)型的數(shù)組,用于存放和返回解析后的數(shù)組Object resolved = Array.newInstance(elementType, ml.size());for (int i = 0; i < ml.size(); i++) {//遞歸解析array的每一個(gè)元素,并將解析后的值設(shè)置到resolved數(shù)組中,索引為iArray.set(resolved, i,resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));}return resolved; }

通過(guò)上面的代碼分析,我們明白了Spring 是如何將引用類(lèi)型,內(nèi)部類(lèi)以及集合類(lèi)型等屬性進(jìn)行解析的,屬性值解析完成后就可以進(jìn)行依賴注入了,依賴注入的過(guò)程就是Bean 對(duì)象實(shí)例設(shè)置到它所依賴的Bean對(duì)象屬性上去。而真正的依賴注入是通過(guò)bw.setPropertyValues()方法實(shí)現(xiàn)的,該方法也使用了委托模式, 在BeanWrapper 接口中至少定義了方法聲明, 依賴注入的具體實(shí)現(xiàn)交由其實(shí)現(xiàn)類(lèi)BeanWrapperImpl 來(lái)完成,下面我們就分析依BeanWrapperImpl 中賴注入相關(guān)的源碼。

?

總結(jié)

以上是生活随笔為你收集整理的解析属性注入规则的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。