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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

注入赋值

發布時間:2024/4/13 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 注入赋值 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

BeanWrapperImpl 類主要是對容器中完成初始化的Bean 實例對象進行屬性的依賴注入,即把Bean對象設置到它所依賴的另一個Bean 的屬性中去。然而,BeanWrapperImpl 中的注入方法實際上由AbstractNestablePropertyAccessor 來實現的,其相關源碼如下:

//實現屬性依賴注入功能 protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {if (tokens.keys != null) {processKeyedProperty(tokens, pv);}else {processLocalProperty(tokens, pv);} } //實現屬性依賴注入功能 @SuppressWarnings("unchecked") private void processKeyedProperty(PropertyTokenHolder tokens, PropertyValue pv) {//調用屬性的getter方法,獲取屬性的值Object propValue = getPropertyHoldingValue(tokens);PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);if (ph == null) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.actualName, "No property handler found");}Assert.state(tokens.keys != null, "No token keys");String lastKey = tokens.keys[tokens.keys.length - 1];//注入array類型的屬性值if (propValue.getClass().isArray()) {Class<?> requiredType = propValue.getClass().getComponentType();int arrayIndex = Integer.parseInt(lastKey);Object oldValue = null;try {if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {oldValue = Array.get(propValue, arrayIndex);}Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),requiredType, ph.nested(tokens.keys.length));//獲取集合類型屬性的長度int length = Array.getLength(propValue);if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {Class<?> componentType = propValue.getClass().getComponentType();Object newArray = Array.newInstance(componentType, arrayIndex + 1);System.arraycopy(propValue, 0, newArray, 0, length);setPropertyValue(tokens.actualName, newArray);//調用屬性的getter方法,獲取屬性的值propValue = getPropertyValue(tokens.actualName);}//將屬性的值賦值給數組中的元素Array.set(propValue, arrayIndex, convertedValue);}catch (IndexOutOfBoundsException ex) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Invalid array index in property path '" + tokens.canonicalName + "'", ex);}}//注入list類型的屬性值else if (propValue instanceof List) {//獲取list集合的類型Class<?> requiredType = ph.getCollectionType(tokens.keys.length);List<Object> list = (List<Object>) propValue;//獲取list集合的sizeint index = Integer.parseInt(lastKey);Object oldValue = null;if (isExtractOldValueForEditor() && index < list.size()) {oldValue = list.get(index);}//獲取list解析后的屬性值Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),requiredType, ph.nested(tokens.keys.length));int size = list.size();//如果list的長度大于屬性值的長度,則多余的元素賦值為nullif (index >= size && index < this.autoGrowCollectionLimit) {for (int i = size; i < index; i++) {try {list.add(null);}catch (NullPointerException ex) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Cannot set element with index " + index + " in List of size " +size + ", accessed using property path '" + tokens.canonicalName +"': List does not support filling up gaps with null elements");}}list.add(convertedValue);}else {try {//將值添加到list中list.set(index, convertedValue);}catch (IndexOutOfBoundsException ex) {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Invalid list index in property path '" + tokens.canonicalName + "'", ex);}}}//注入map類型的屬性值else if (propValue instanceof Map) {//獲取map集合key的類型Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);//獲取map集合value的類型Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);Map<Object, Object> map = (Map<Object, Object>) propValue;// IMPORTANT: Do not pass full property name in here - property editors// must not kick in for map keys but rather only for map values.TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);//解析map類型屬性key值Object convertedMapKey = convertIfNecessary(null, null, lastKey, mapKeyType, typeDescriptor);Object oldValue = null;if (isExtractOldValueForEditor()) {oldValue = map.get(convertedMapKey);}// Pass full property name and old value in here, since we want full// conversion ability for map values.//解析map類型屬性value值Object convertedMapValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),mapValueType, ph.nested(tokens.keys.length));//將解析后的key和value值賦值給map集合屬性map.put(convertedMapKey, convertedMapValue);}else {throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Property referenced in indexed property path '" + tokens.canonicalName +"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");} } private Object getPropertyHoldingValue(PropertyTokenHolder tokens) {// Apply indexes and map keys: fetch value for all keys but the last one.Assert.state(tokens.keys != null, "No token keys");PropertyTokenHolder getterTokens = new PropertyTokenHolder(tokens.actualName);getterTokens.canonicalName = tokens.canonicalName;getterTokens.keys = new String[tokens.keys.length - 1];System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);Object propValue;try {//獲取屬性值propValue = getPropertyValue(getterTokens);}catch (NotReadablePropertyException ex) {throw new NotWritablePropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,"Cannot access indexed value in property referenced " +"in indexed property path '" + tokens.canonicalName + "'", ex);}if (propValue == null) {// null map value caseif (isAutoGrowNestedPaths()) {int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);propValue = setDefaultValue(getterTokens);}else {throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,"Cannot access indexed value in property referenced " +"in indexed property path '" + tokens.canonicalName + "': returned null");}}return propValue; }

通過對上面注入依賴代碼的分析,我們已經明白了Spring IOC 容器是如何將屬性的值注入到Bean 實例對象中去的:

1)、對于集合類型的屬性,將其屬性值解析為目標類型的集合后直接賦值給屬性。

2)、對于非集合類型的屬性,大量使用了JDK 的反射機制,通過屬性的getter()方法獲取指定屬性注入以前的值,同時調用屬性的setter()方法為屬性設置注入后的值。看到這里相信很多人都明白了Spring的setter()注入原理。

至此Spring IOC 容器對Bean 定義資源文件的定位,載入、解析和依賴注入已經全部分析完畢,現在Spring IOC 容器中管理了一系列靠依賴關系聯系起來的Bean,程序不需要應用自己手動創建所需的對象,Spring IOC 容器會在我們使用的時候自動為我們創建,并且為我們注入好相關的依賴,這就是Spring 核心功能的控制反轉和依賴注入的相關功能。

?

總結

以上是生活随笔為你收集整理的注入赋值的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。