1 16 17 package org.springframework.beans.factory.support; 18 19 import java.util.ArrayList ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 import java.util.Properties ; 24 import java.util.Set ; 25 26 import org.springframework.beans.BeanWrapper; 27 import org.springframework.beans.BeansException; 28 import org.springframework.beans.TypeConverter; 29 import org.springframework.beans.factory.BeanCreationException; 30 import org.springframework.beans.factory.BeanDefinitionStoreException; 31 import org.springframework.beans.factory.config.BeanDefinition; 32 import org.springframework.beans.factory.config.BeanDefinitionHolder; 33 import org.springframework.beans.factory.config.RuntimeBeanNameReference; 34 import org.springframework.beans.factory.config.RuntimeBeanReference; 35 import org.springframework.beans.factory.config.TypedStringValue; 36 import org.springframework.core.CollectionFactory; 37 38 51 class BeanDefinitionValueResolver { 52 53 57 public static final String GENERATED_BEAN_NAME_SEPARATOR = 58 BeanDefinitionReaderUtils.GENERATED_BEAN_NAME_SEPARATOR; 59 60 61 private final AbstractBeanFactory beanFactory; 62 63 private final String beanName; 64 65 private final BeanDefinition beanDefinition; 66 67 private final TypeConverter typeConverter; 68 69 70 78 public BeanDefinitionValueResolver( 79 AbstractBeanFactory beanFactory, String beanName, BeanDefinition beanDefinition, TypeConverter typeConverter) { 80 81 this.beanFactory = beanFactory; 82 this.beanName = beanName; 83 this.beanDefinition = beanDefinition; 84 this.typeConverter = typeConverter; 85 } 86 87 105 public Object resolveValueIfNecessary(String argName, Object value) { 106 if (value instanceof BeanDefinitionHolder) { 109 BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value; 111 return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition()); 112 } 113 else if (value instanceof BeanDefinition) { 114 BeanDefinition bd = (BeanDefinition) value; 116 return resolveInnerBean(argName, "(inner bean)", bd); 117 } 118 else if (value instanceof RuntimeBeanNameReference) { 119 String ref = ((RuntimeBeanNameReference) value).getBeanName(); 120 if (!this.beanFactory.containsBean(ref)) { 121 throw new BeanDefinitionStoreException( 122 "Invalid bean name '" + ref + "' in bean reference for " + argName); 123 } 124 return ref; 125 } 126 else if (value instanceof RuntimeBeanReference) { 127 RuntimeBeanReference ref = (RuntimeBeanReference) value; 128 return resolveReference(argName, ref); 129 } 130 else if (value instanceof ManagedList) { 131 return resolveManagedList(argName, (List ) value); 133 } 134 else if (value instanceof ManagedSet) { 135 return resolveManagedSet(argName, (Set ) value); 137 } 138 else if (value instanceof ManagedMap) { 139 return resolveManagedMap(argName, (Map ) value); 141 } 142 else if (value instanceof ManagedProperties) { 143 Properties original = (Properties ) value; 144 Properties copy = new Properties (); 145 for (Iterator it = original.entrySet().iterator(); it.hasNext();) { 146 Map.Entry propEntry = (Map.Entry ) it.next(); 147 Object propKey = propEntry.getKey(); 148 Object propValue = propEntry.getValue(); 149 if (propKey instanceof TypedStringValue) { 150 propKey = ((TypedStringValue) propKey).getValue(); 151 } 152 if (propValue instanceof TypedStringValue) { 153 propValue = ((TypedStringValue) propValue).getValue(); 154 } 155 copy.put(propKey, propValue); 156 } 157 return copy; 158 } 159 else if (value instanceof TypedStringValue) { 160 TypedStringValue typedStringValue = (TypedStringValue) value; 162 try { 163 Class resolvedTargetType = resolveTargetType(typedStringValue); 164 if (resolvedTargetType != null) { 165 return this.beanFactory.doTypeConversionIfNecessary( 166 this.typeConverter, typedStringValue.getValue(), resolvedTargetType, null); 167 } 168 else { 169 return typedStringValue.getValue(); 171 } 172 } 173 catch (Throwable ex) { 174 throw new BeanCreationException( 176 this.beanDefinition.getResourceDescription(), this.beanName, 177 "Error converting typed String value for " + argName, ex); 178 } 179 } 180 else { 181 return value; 183 } 184 } 185 186 193 protected Class resolveTargetType(TypedStringValue value) throws ClassNotFoundException { 194 if (value.hasTargetType()) { 195 return value.getTargetType(); 196 } 197 return value.resolveTargetType(this.beanFactory.getBeanClassLoader()); 198 } 199 200 207 private Object resolveInnerBean(String argName, String innerBeanName, BeanDefinition innerBd) { 208 if (this.beanFactory.logger.isTraceEnabled()) { 209 this.beanFactory.logger.trace( 210 "Resolving inner bean definition '" + innerBeanName + "' of bean '" + this.beanName + "'"); 211 } 212 RootBeanDefinition mbd = null; 213 try { 214 mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition); 215 String actualInnerBeanName = innerBeanName; 218 if (mbd.isSingleton()) { 219 actualInnerBeanName = adaptInnerBeanName(innerBeanName); 220 } 221 Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null); 222 if (mbd.isSingleton()) { 223 this.beanFactory.registerDependentBean(actualInnerBeanName, this.beanName); 224 } 225 return this.beanFactory.getObjectForBeanInstance(innerBean, actualInnerBeanName, mbd); 226 } 227 catch (BeansException ex) { 228 throw new BeanCreationException( 229 this.beanDefinition.getResourceDescription(), this.beanName, 230 "Cannot create inner bean '" + innerBeanName + "' " + 231 (mbd != null && mbd.getBeanClassName() != null ? "of type [" + mbd.getBeanClassName() + "] " : "") + 232 "while setting " + argName, ex); 233 } 234 } 235 236 242 private String adaptInnerBeanName(String innerBeanName) { 243 String actualInnerBeanName = innerBeanName; 244 int counter = 0; 245 while (this.beanFactory.isBeanNameInUse(actualInnerBeanName)) { 246 counter++; 247 actualInnerBeanName = innerBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter; 248 } 249 return actualInnerBeanName; 250 } 251 252 255 private Object resolveReference(String argName, RuntimeBeanReference ref) { 256 if (this.beanFactory.logger.isTraceEnabled()) { 257 this.beanFactory.logger.trace("Resolving reference from property " + argName + " in bean '" + 258 this.beanName + "' to bean '" + ref.getBeanName() + "'"); 259 } 260 try { 261 if (ref.isToParent()) { 262 if (this.beanFactory.getParentBeanFactory() == null) { 263 throw new BeanCreationException( 264 this.beanDefinition.getResourceDescription(), this.beanName, 265 "Can't resolve reference to bean '" + ref.getBeanName() + 266 "' in parent factory: no parent factory available"); 267 } 268 return this.beanFactory.getParentBeanFactory().getBean(ref.getBeanName()); 269 } 270 else { 271 Object bean = this.beanFactory.getBean(ref.getBeanName()); 272 if (this.beanDefinition.isSingleton()) { 273 this.beanFactory.registerDependentBean(ref.getBeanName(), this.beanName); 274 } 275 return bean; 276 } 277 } 278 catch (BeansException ex) { 279 throw new BeanCreationException( 280 this.beanDefinition.getResourceDescription(), this.beanName, 281 "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex); 282 } 283 } 284 285 288 private List resolveManagedList(String argName, List ml) { 289 List resolved = new ArrayList (ml.size()); 290 for (int i = 0; i < ml.size(); i++) { 291 resolved.add( 292 resolveValueIfNecessary( 293 argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX, 294 ml.get(i))); 295 } 296 return resolved; 297 } 298 299 302 private Set resolveManagedSet(String argName, Set ms) { 303 Set resolved = CollectionFactory.createLinkedSetIfPossible(ms.size()); 304 int i = 0; 305 for (Iterator it = ms.iterator(); it.hasNext();) { 306 resolved.add( 307 resolveValueIfNecessary( 308 argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + i + BeanWrapper.PROPERTY_KEY_SUFFIX, 309 it.next())); 310 i++; 311 } 312 return resolved; 313 } 314 315 318 private Map resolveManagedMap(String argName, Map mm) { 319 Map resolved = CollectionFactory.createLinkedMapIfPossible(mm.size()); 320 Iterator it = mm.entrySet().iterator(); 321 while (it.hasNext()) { 322 Map.Entry entry = (Map.Entry ) it.next(); 323 Object resolvedKey = resolveValueIfNecessary(argName, entry.getKey()); 324 Object resolvedValue = resolveValueIfNecessary( 325 argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX + entry.getKey() + BeanWrapper.PROPERTY_KEY_SUFFIX, 326 entry.getValue()); 327 resolved.put(resolvedKey, resolvedValue); 328 } 329 return resolved; 330 } 331 332 } 333 | Popular Tags |