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