1 16 17 package org.springframework.beans.factory.support; 18 19 import java.util.ArrayList ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 25 import org.springframework.beans.BeansException; 26 import org.springframework.beans.factory.BeanCreationException; 27 import org.springframework.beans.factory.BeanCurrentlyInCreationException; 28 import org.springframework.beans.factory.BeanDefinitionStoreException; 29 import org.springframework.beans.factory.BeanFactory; 30 import org.springframework.beans.factory.BeanFactoryUtils; 31 import org.springframework.beans.factory.CannotLoadBeanClassException; 32 import org.springframework.beans.factory.FactoryBean; 33 import org.springframework.beans.factory.NoSuchBeanDefinitionException; 34 import org.springframework.beans.factory.config.BeanDefinition; 35 import org.springframework.beans.factory.config.ConfigurableBeanFactory; 36 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 37 import org.springframework.core.CollectionFactory; 38 import org.springframework.util.Assert; 39 import org.springframework.util.ObjectUtils; 40 import org.springframework.util.StringUtils; 41 42 72 public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory 73 implements ConfigurableListableBeanFactory, BeanDefinitionRegistry { 74 75 76 private boolean allowBeanDefinitionOverriding = true; 77 78 79 private boolean allowEagerClassLoading = true; 80 81 82 private final Map beanDefinitionMap = new HashMap (); 83 84 85 private final List beanDefinitionNames = new ArrayList (); 86 87 88 91 public DefaultListableBeanFactory() { 92 super(); 93 } 94 95 99 public DefaultListableBeanFactory(BeanFactory parentBeanFactory) { 100 super(parentBeanFactory); 101 } 102 103 104 109 public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) { 110 this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding; 111 } 112 113 123 public void setAllowEagerClassLoading(boolean allowEagerClassLoading) { 124 this.allowEagerClassLoading = allowEagerClassLoading; 125 } 126 127 128 public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { 129 super.copyConfigurationFrom(otherFactory); 130 if (otherFactory instanceof DefaultListableBeanFactory) { 131 DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory) otherFactory; 132 this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding; 133 this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading; 134 } 135 } 136 137 138 142 public boolean containsBeanDefinition(String beanName) { 143 return this.beanDefinitionMap.containsKey(beanName); 144 } 145 146 public int getBeanDefinitionCount() { 147 return this.beanDefinitionMap.size(); 148 } 149 150 public String [] getBeanDefinitionNames() { 151 return StringUtils.toStringArray(this.beanDefinitionNames); 152 } 153 154 public String [] getBeanNamesForType(Class type) { 155 return getBeanNamesForType(type, true, true); 156 } 157 158 public String [] getBeanNamesForType(Class type, boolean includePrototypes, boolean allowEagerInit) { 159 List result = new ArrayList (); 160 161 for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) { 163 String beanName = (String ) it.next(); 164 if (!isAlias(beanName)) { 167 RootBeanDefinition mbd = getMergedBeanDefinition(beanName, false); 168 if (!mbd.isAbstract() && 170 (allowEagerInit || mbd.hasBeanClass() || !mbd.isLazyInit() || this.allowEagerClassLoading)) { 171 try { 173 boolean isFactoryBean = isBeanClassMatch(beanName, mbd, FactoryBean.class); 174 if (isFactoryBean || mbd.getFactoryBeanName() != null) { 175 if (allowEagerInit && (includePrototypes || isSingleton(beanName)) && isTypeMatch(beanName, type)) { 176 result.add(beanName); 177 continue; 179 } 180 if (!isFactoryBean) { 182 continue; 183 } 184 beanName = FACTORY_BEAN_PREFIX + beanName; 186 } 187 if ((includePrototypes || mbd.isSingleton()) && isTypeMatch(beanName, type)) { 189 result.add(beanName); 190 } 191 } 192 catch (CannotLoadBeanClassException ex) { 193 if (mbd.isLazyInit()) { 194 if (logger.isDebugEnabled()) { 195 logger.debug("Ignoring bean class loading failure for lazy-init bean '" + beanName + "'", ex); 196 } 197 } 198 else { 199 throw ex; 200 } 201 } 202 } 203 } 204 } 205 206 String [] singletonNames = getSingletonNames(); 208 for (int i = 0; i < singletonNames.length; i++) { 209 String beanName = singletonNames[i]; 210 if (!containsBeanDefinition(beanName)) { 212 if (isFactoryBean(beanName)) { 214 if ((includePrototypes || isSingleton(beanName)) && isTypeMatch(beanName, type)) { 215 result.add(beanName); 216 continue; 218 } 219 beanName = FACTORY_BEAN_PREFIX + beanName; 221 } 222 if (isTypeMatch(beanName, type)) { 224 result.add(beanName); 225 } 226 } 227 } 228 229 return StringUtils.toStringArray(result); 230 } 231 232 public Map getBeansOfType(Class type) throws BeansException { 233 return getBeansOfType(type, true, true); 234 } 235 236 public Map getBeansOfType(Class type, boolean includePrototypes, boolean allowEagerInit) 237 throws BeansException { 238 239 String [] beanNames = getBeanNamesForType(type, includePrototypes, allowEagerInit); 240 Map result = CollectionFactory.createLinkedMapIfPossible(beanNames.length); 241 for (int i = 0; i < beanNames.length; i++) { 242 String beanName = beanNames[i]; 243 try { 244 result.put(beanName, getBean(beanName)); 245 } 246 catch (BeanCreationException ex) { 247 Throwable rootCause = ex.getMostSpecificCause(); 248 if (rootCause instanceof BeanCurrentlyInCreationException) { 249 BeanCreationException bce = (BeanCreationException) rootCause; 250 if (isCurrentlyInCreation(bce.getBeanName())) { 251 if (logger.isDebugEnabled()) { 252 logger.debug("Ignoring match to currently created bean '" + beanName + "': " + ex.getMessage()); 253 } 254 continue; 257 } 258 } 259 throw ex; 260 } 261 } 262 return result; 263 } 264 265 266 270 public void preInstantiateSingletons() throws BeansException { 271 if (logger.isInfoEnabled()) { 272 logger.info("Pre-instantiating singletons in " + this); 273 } 274 for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) { 275 String beanName = (String ) it.next(); 276 if (!containsSingleton(beanName) && containsBeanDefinition(beanName)) { 277 RootBeanDefinition bd = getMergedBeanDefinition(beanName, false); 278 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 279 Class beanClass = resolveBeanClass(bd, beanName); 280 if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { 281 getBean(FACTORY_BEAN_PREFIX + beanName); 282 } 283 else { 284 getBean(beanName); 285 } 286 } 287 } 288 } 289 } 290 291 292 296 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 297 throws BeanDefinitionStoreException { 298 299 Assert.hasText(beanName, "'beanName' must not be empty"); 300 Assert.notNull(beanDefinition, "BeanDefinition must not be null"); 301 302 if (beanDefinition instanceof AbstractBeanDefinition) { 303 try { 304 ((AbstractBeanDefinition) beanDefinition).validate(); 305 } 306 catch (BeanDefinitionValidationException ex) { 307 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 308 "Validation of bean definition failed", ex); 309 } 310 } 311 312 Object oldBeanDefinition = this.beanDefinitionMap.get(beanName); 313 if (oldBeanDefinition != null) { 314 if (!this.allowBeanDefinitionOverriding) { 315 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 316 "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + 317 "': There is already [" + oldBeanDefinition + "] bound."); 318 } 319 else { 320 if (logger.isInfoEnabled()) { 321 logger.info("Overriding bean definition for bean '" + beanName + 322 "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); 323 } 324 } 325 } 326 else { 327 this.beanDefinitionNames.add(beanName); 328 } 329 this.beanDefinitionMap.put(beanName, beanDefinition); 330 331 synchronized (getSingletonMutex()) { 335 removeSingleton(beanName); 336 } 337 } 338 339 340 344 public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { 345 BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.get(beanName); 346 if (bd == null) { 347 if (logger.isTraceEnabled()) { 348 logger.trace("No bean named '" + beanName + "' found in " + this); 349 } 350 throw new NoSuchBeanDefinitionException(beanName); 351 } 352 return bd; 353 } 354 355 protected Map findAutowireCandidates(String beanName, Class requiredType) { 356 String [] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType); 357 Map result = CollectionFactory.createLinkedMapIfPossible(candidateNames.length); 358 for (int i = 0; i < candidateNames.length; i++) { 359 String candidateName = candidateNames[i]; 360 if (!candidateName.equals(beanName) && 361 (!containsBeanDefinition(candidateName) || getMergedBeanDefinition(candidateName).isAutowireCandidate())) { 362 result.put(candidateName, getBean(candidateName)); 363 } 364 } 365 return result; 366 } 367 368 369 public String toString() { 370 StringBuffer sb = new StringBuffer (ObjectUtils.identityToString(this)); 371 sb.append(": defining beans ["); 372 sb.append(StringUtils.arrayToCommaDelimitedString(getBeanDefinitionNames())); 373 sb.append("]; "); 374 BeanFactory parent = getParentBeanFactory(); 375 if (parent == null) { 376 sb.append("root of factory hierarchy"); 377 } 378 else { 379 sb.append("parent: " + ObjectUtils.identityToString(parent)); 380 } 381 return sb.toString(); 382 } 383 384 } 385 | Popular Tags |