您好,登錄后才能下訂單哦!
這篇文章主要介紹了Spring怎么正確注入集合類型,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
集合類型的自動(dòng)注入是Spring提供的另外一個(gè)強(qiáng)大功能。我們?cè)诜奖愕氖褂靡蕾囎⑷氲奶匦詴r(shí),必須要思考對(duì)象從哪里注入、怎么創(chuàng)建、為什么是注入這一個(gè)對(duì)象的。雖然編寫框架的目的是讓開發(fā)人員無需關(guān)心太多底層細(xì)節(jié),能專心業(yè)務(wù)邏輯的開發(fā),但是作為開發(fā)人員不能真的無腦去使用框架。
現(xiàn)在有一需求:存在多個(gè)用戶Bean,找出來存儲(chǔ)到一個(gè)List。
多個(gè)用戶Bean定義:
有了集合類型的自動(dòng)注入后,即可收集零散的用戶Bean:
這樣即可完成集合類型注入:
但當(dāng)持續(xù)增加一些user時(shí),可能就不喜歡用上述的注入集合類型了,而是這樣:
分開玩,大家應(yīng)該不會(huì)有啥問題,若兩種方式共存了,會(huì)咋樣?
運(yùn)行程序后發(fā)現(xiàn)直接裝配方式的未生效:
這是為啥呢?
就得精通這兩種注入風(fēng)格在Spring分別如何實(shí)現(xiàn)的。
DefaultListableBeanFactory#resolveMultipleBeans
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) { final Class<?> type = descriptor.getDependencyType(); if (descriptor instanceof StreamDependencyDescriptor) { // 裝配stream return stream; } else if (type.isArray()) { // 裝配數(shù)組 return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { // 裝配集合 // 獲取集合的元素類型 Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); if (elementType == null) { return null; } // 根據(jù)元素類型查找所有的bean Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } // 轉(zhuǎn)化查到的所有bean放置到集合并返回 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); // ... return result; } else if (Map.class == type) { // 解析map return matchingBeans; } else { return null; } }
目標(biāo)類型定義為List users,所以元素類型為User:
有了elementType,即可據(jù)其找出所有Bean:
上一步獲取的所有的Bean都以java.util.LinkedHashMap.LinkedValues
存儲(chǔ),和目標(biāo)類型大不相同,所以最后按需轉(zhuǎn)化。
本案例中,需轉(zhuǎn)化為List:
DefaultListableBeanFactory#findAutowireCandidates
不再贅述。
最后就是根據(jù)目標(biāo)類型直接尋找匹配Bean名稱為users的List<user>
裝配給userController#users屬性。
當(dāng)同時(shí)滿足這兩種裝配方式時(shí),Spring會(huì)如何處理呢?
DefaultListableBeanFactory#doResolveDependency
顯然這兩種裝配集合的方式不能同存,結(jié)合本案例:
當(dāng)使用收集裝配時(shí),能找到任一對(duì)應(yīng)Bean,則返回
若一個(gè)都沒找到,才采用直接裝配
所以后期以List方式直接添加的user Bean都不生效!
務(wù)必避免兩種方式共存去裝配集合!只選用一種方式即可。
比如只使用直接裝配:
只使用收集方式:
如何做到讓用戶2優(yōu)先輸出呢?
控制spring bean加載順序:
Bean上使用@Order注解,如@Order(2)。數(shù)值越小表示優(yōu)先級(jí)越高。默認(rèn)優(yōu)先級(jí)最低。
@DependsOn 使用它,可使得依賴的Bean如果未被初始化會(huì)被優(yōu)先初始化。
添加@Order(number)注解,number越小優(yōu)先級(jí)越高,越靠前聲
明user這些Bean時(shí)將id=2的user提到id=1之前
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Spring怎么正確注入集合類型”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。