1. 程式人生 > >Spring:原始碼解讀Spring IOC原理

Spring:原始碼解讀Spring IOC原理

1 //實現屬性依賴注入功能 2 private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException { 3 //PropertyTokenHolder主要儲存屬性的名稱、路徑,以及集合的size等資訊 4 String propertyName = tokens.canonicalName; 5 String actualName = tokens.actualName; 6 //
keys是用來儲存集合型別屬性的size 7 if (tokens.keys != null) { 8 //將屬性資訊拷貝 9 PropertyTokenHolder getterTokens = new PropertyTokenHolder(); 10 getterTokens.canonicalName = tokens.canonicalName; 11 getterTokens.actualName = tokens.actualName; 12 getterTokens.keys = new
String[tokens.keys.length - 1]; 13 System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1); 14 Object propValue; 15 try { 16 //獲取屬性值,該方法內部使用JDK的內省( Introspector)機制,呼叫屬性//的getter(readerMethod)方法,獲取屬性的值 17 propValue = getPropertyValue(getterTokens);
18 } 19 catch (NotReadablePropertyException ex) { 20 throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName, 21 "Cannot access indexed value in property referenced " + 22 "in indexed property path '" + propertyName + "'", ex); 23 } 24 //獲取集合型別屬性的長度 25 String key = tokens.keys[tokens.keys.length - 1]; 26 if (propValue == null) { 27 throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName, 28 "Cannot access indexed value in property referenced " + 29 "in indexed property path '" + propertyName + "': returned null"); 30 } 31 //注入array型別的屬性值 32 else if (propValue.getClass().isArray()) { 33 //獲取屬性的描述符 34 PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); 35 //獲取陣列的型別 36 Class requiredType = propValue.getClass().getComponentType(); 37 //獲取陣列的長度 38 int arrayIndex = Integer.parseInt(key); 39 Object oldValue = null; 40 try { 41 //獲取陣列以前初始化的值 42 if (isExtractOldValueForEditor()) { 43 oldValue = Array.get(propValue, arrayIndex); 44 } 45 //將屬性的值賦值給陣列中的元素 46 Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, 47 new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType)); 48 Array.set(propValue, arrayIndex, convertedValue); 49 } 50 catch (IndexOutOfBoundsException ex) { 51 throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, 52 "Invalid array index in property path '" + propertyName + "'", ex); 53 } 54 } 55 //注入list型別的屬性值 56 else if (propValue instanceof List) { 57 PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); 58 //獲取list集合的型別 59 Class requiredType = GenericCollectionTypeResolver.getCollectionReturnType( 60 pd.getReadMethod(), tokens.keys.length); 61 List list = (List) propValue; 62 //獲取list集合的size 63 int index = Integer.parseInt(key); 64 Object oldValue = null; 65 if (isExtractOldValueForEditor() && index < list.size()) { 66 oldValue = list.get(index); 67 } 68 //獲取list解析後的屬性值 69 Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, 70 new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType)); 71 if (index < list.size()) { 72 //為list屬性賦值 73 list.set(index, convertedValue); 74 } 75 //如果list的長度大於屬性值的長度,則多餘的元素賦值為null 76 else if (index >= list.size()) { 77 for (int i = list.size(); i < index; i++) { 78 try { 79 list.add(null); 80 } 81 catch (NullPointerException ex) { 82 throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, 83 "Cannot set element with index " + index + " in List of size " + 84 list.size() + ", accessed using property path '" + propertyName + 85 "': List does not support filling up gaps with null elements"); 86 } 87 } 88 list.add(convertedValue); 89 } 90 } 91 //注入map型別的屬性值 92 else if (propValue instanceof Map) { 93 PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); 94 //獲取map集合key的型別 95 Class mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType( 96 pd.getReadMethod(), tokens.keys.length); 97 //獲取map集合value的型別 98 Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType( 99 pd.getReadMethod(), tokens.keys.length); 100 Map map = (Map) propValue; 101 //解析map型別屬性key值 102 Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, 103 new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), mapKeyType)); 104 Object oldValue = null; 105 if (isExtractOldValueForEditor()) { 106 oldValue = map.get(convertedMapKey); 107 } 108 //解析map型別屬性value值 109 Object convertedMapValue = convertIfNecessary( 110 propertyName, oldValue, pv.getValue(), mapValueType, 111 new TypeDescriptor(new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1))); 112 //將解析後的key和value值賦值給map集合屬性 113 map.put(convertedMapKey, convertedMapValue); 114 } 115 else { 116 throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName, 117 "Property referenced in indexed property path '" + propertyName + 118 "' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]"); 119 } 120 } 121 //對非集合型別的屬性注入 122 else { 123 PropertyDescriptor pd = pv.resolvedDescriptor; 124 if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) { 125 pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); 126 //無法獲取到屬性名或者屬性沒有提供setter(寫方法)方法 127 if (pd == null || pd.getWriteMethod() == null) { 128 //如果屬性值是可選的,即不是必須的,則忽略該屬性值 129 if (pv.isOptional()) { 130 logger.debug("Ignoring optional value for property '" + actualName + 131 "' - property not found on bean class [" + getRootClass().getName() + "]"); 132 return; 133 } 134 //如果屬性值是必須的,則丟擲無法給屬性賦值,因為每天提供setter方法異常 135 else { 136 PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass()); 137 throw new NotWritablePropertyException( 138 getRootClass(), this.nestedPath + propertyName, 139 matches.buildErrorMessage(), matches.getPossibleMatches()); 140 } 141 } 142 pv.getOriginalPropertyValue().resolvedDescriptor = pd; 143 } 144 Object oldValue = null; 145 try { 146 Object originalValue = pv.getValue(); 147 Object valueToApply = originalValue; 148 if (!Boolean.FALSE.equals(pv.conversionNecessary)) { 149 if (pv.isConverted()) { 150 valueToApply = pv.getConvertedValue(); 151 } 152 else { 153 if (isExtractOldValueForEditor() && pd.getReadMethod() != null) { 154 //獲取屬性的getter方法(讀方法),JDK內省機制 155 final Method readMethod = pd.getReadMethod(); 156 //如果屬性的getter方法不是public訪問控制權限的,即訪問控制權限比較嚴格, 157 //則使用JDK的反射機制強行訪問非public的方法(暴力讀取屬性值) 158 if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && 159 !readMethod.isAccessible()) { 160 if (System.getSecurityManager()!= null) { 161 //匿名內部類,根據許可權修改屬性的讀取控制限制 162 AccessController.doPrivileged(new PrivilegedAction<Object>() { 163 public Object run() { 164 readMethod.setAccessible(true); 165 return null; 166 } 167 }); 168 } 169 else { 170 readMethod.setAccessible(true); 171 } 172 } 173 try { 174 //屬性沒有提供getter方法時,呼叫潛在的讀取屬性值//的方法,獲取屬性值 175 if (System.getSecurityManager() != null) { 176 oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 177 public Object run() throws Exception { 178 return readMethod.invoke(object); 179 } 180 }, acc); 181 } 182 else { 183 oldValue = readMethod.invoke(object); 184 } 185 } 186 catch (Exception ex) { 187 if (ex instanceof PrivilegedActionException) { 188 ex = ((PrivilegedActionException) ex).getException(); 189 } 190 if (logger.isDebugEnabled()) { 191 logger.debug("Could not read previous value of property '" + 192 this.nestedPath + propertyName + "'", ex); 193 } 194 } 195 } 196 //設定屬性的注入值 197 valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd); 198 } 199 pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue); 200 } 201 //根據JDK的內省機制,獲取屬性的setter(寫方法)方法 202 final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ? 203 ((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() : 204 pd.getWriteMethod()); 205 //如果屬性的setter方法是非public,即訪問控制權限比較嚴格,則使用JDK的反射機制, 206 //強行設定setter方法可訪問(暴力為屬性賦值) 207 if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) { 208 //如果使用了JDK的安全機制,則需要許可權驗證 209 if (System.getSecurityManager()!= null) { 210 AccessController.doPrivileged(new PrivilegedAction<Object>() { 211 public Object run() { 212 writeMethod.setAccessible(true); 213 return null; 214 } 215 }); 216 } 217 else { 218 writeMethod.setAccessible(true); 219 } 220 } 221 final Object value = valueToApply; 222 if (System.getSecurityManager() != null) { 223 try { 224 //將屬性值設定到屬性上去 225 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 226 public Object run() throws Exception { 227 writeMethod.invoke(object, value); 228 return null; 229 } 230 }, acc); 231 } 232 catch (PrivilegedActionException ex) { 233 throw ex.getException(); 234 } 235 } 236 else { 237 writeMethod.invoke(this.object, value); 238 } 239 } 240 catch (TypeMismatchException ex) { 241 throw ex; 242 } 243 catch (InvocationTargetException ex) { 244 PropertyChangeEvent propertyChangeEvent = 245 new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue()); 246 if (ex.getTargetException() instanceof ClassCastException) { 247 throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException()); 248 } 249 else { 250 throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException()); 251 } 252 } 253 catch (Exception ex) { 254 PropertyChangeEvent pce = 255 new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue()); 256 throw new MethodInvocationException(pce, ex); 257 } 258 } }