001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory.support; 018 019import java.io.IOException; 020import java.io.NotSerializableException; 021import java.io.ObjectInputStream; 022import java.io.ObjectStreamException; 023import java.io.Serializable; 024import java.lang.annotation.Annotation; 025import java.lang.ref.Reference; 026import java.lang.ref.WeakReference; 027import java.lang.reflect.Method; 028import java.security.AccessController; 029import java.security.PrivilegedAction; 030import java.util.ArrayList; 031import java.util.Arrays; 032import java.util.Collection; 033import java.util.Collections; 034import java.util.Comparator; 035import java.util.IdentityHashMap; 036import java.util.Iterator; 037import java.util.LinkedHashMap; 038import java.util.LinkedHashSet; 039import java.util.List; 040import java.util.Map; 041import java.util.Optional; 042import java.util.Set; 043import java.util.concurrent.ConcurrentHashMap; 044import javax.inject.Provider; 045 046import org.springframework.beans.BeanUtils; 047import org.springframework.beans.BeansException; 048import org.springframework.beans.TypeConverter; 049import org.springframework.beans.factory.BeanCreationException; 050import org.springframework.beans.factory.BeanCurrentlyInCreationException; 051import org.springframework.beans.factory.BeanDefinitionStoreException; 052import org.springframework.beans.factory.BeanFactory; 053import org.springframework.beans.factory.BeanFactoryAware; 054import org.springframework.beans.factory.BeanFactoryUtils; 055import org.springframework.beans.factory.BeanNotOfRequiredTypeException; 056import org.springframework.beans.factory.CannotLoadBeanClassException; 057import org.springframework.beans.factory.FactoryBean; 058import org.springframework.beans.factory.InjectionPoint; 059import org.springframework.beans.factory.NoSuchBeanDefinitionException; 060import org.springframework.beans.factory.NoUniqueBeanDefinitionException; 061import org.springframework.beans.factory.ObjectFactory; 062import org.springframework.beans.factory.ObjectProvider; 063import org.springframework.beans.factory.SmartFactoryBean; 064import org.springframework.beans.factory.SmartInitializingSingleton; 065import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 066import org.springframework.beans.factory.config.BeanDefinition; 067import org.springframework.beans.factory.config.BeanDefinitionHolder; 068import org.springframework.beans.factory.config.ConfigurableBeanFactory; 069import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 070import org.springframework.beans.factory.config.DependencyDescriptor; 071import org.springframework.beans.factory.config.NamedBeanHolder; 072import org.springframework.core.OrderComparator; 073import org.springframework.core.ResolvableType; 074import org.springframework.core.annotation.AnnotationUtils; 075import org.springframework.lang.UsesJava8; 076import org.springframework.util.Assert; 077import org.springframework.util.ClassUtils; 078import org.springframework.util.CompositeIterator; 079import org.springframework.util.ObjectUtils; 080import org.springframework.util.StringUtils; 081 082/** 083 * Spring's default implementation of the {@link ConfigurableListableBeanFactory} 084 * and {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory 085 * based on bean definition metadata, extensible through post-processors. 086 * 087 * <p>Typical usage is registering all bean definitions first (possibly read 088 * from a bean definition file), before accessing beans. Bean lookup by name 089 * is therefore an inexpensive operation in a local bean definition table, 090 * operating on pre-resolved bean definition metadata objects. 091 * 092 * <p>Note that readers for specific bean definition formats are typically 093 * implemented separately rather than as bean factory subclasses: see for example 094 * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}. 095 * 096 * <p>For an alternative implementation of the 097 * {@link org.springframework.beans.factory.ListableBeanFactory} interface, 098 * have a look at {@link StaticListableBeanFactory}, which manages existing 099 * bean instances rather than creating new ones based on bean definitions. 100 * 101 * @author Rod Johnson 102 * @author Juergen Hoeller 103 * @author Sam Brannen 104 * @author Costin Leau 105 * @author Chris Beams 106 * @author Phillip Webb 107 * @author Stephane Nicoll 108 * @since 16 April 2001 109 * @see #registerBeanDefinition 110 * @see #addBeanPostProcessor 111 * @see #getBean 112 * @see #resolveDependency 113 */ 114@SuppressWarnings("serial") 115public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory 116 implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { 117 118 private static Class<?> javaUtilOptionalClass = null; 119 120 private static Class<?> javaxInjectProviderClass = null; 121 122 static { 123 try { 124 javaUtilOptionalClass = 125 ClassUtils.forName("java.util.Optional", DefaultListableBeanFactory.class.getClassLoader()); 126 } 127 catch (ClassNotFoundException ex) { 128 // Java 8 not available - Optional references simply not supported then. 129 } 130 try { 131 javaxInjectProviderClass = 132 ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader()); 133 } 134 catch (ClassNotFoundException ex) { 135 // JSR-330 API not available - Provider interface simply not supported then. 136 } 137 } 138 139 140 /** Map from serialized id to factory instance */ 141 private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories = 142 new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8); 143 144 /** Optional id for this factory, for serialization purposes */ 145 private String serializationId; 146 147 /** Whether to allow re-registration of a different definition with the same name */ 148 private boolean allowBeanDefinitionOverriding = true; 149 150 /** Whether to allow eager class loading even for lazy-init beans */ 151 private boolean allowEagerClassLoading = true; 152 153 /** Optional OrderComparator for dependency Lists and arrays */ 154 private Comparator<Object> dependencyComparator; 155 156 /** Resolver to use for checking if a bean definition is an autowire candidate */ 157 private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); 158 159 /** Map from dependency type to corresponding autowired value */ 160 private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16); 161 162 /** Map of bean definition objects, keyed by bean name */ 163 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256); 164 165 /** Map of singleton and non-singleton bean names, keyed by dependency type */ 166 private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); 167 168 /** Map of singleton-only bean names, keyed by dependency type */ 169 private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); 170 171 /** List of bean definition names, in registration order */ 172 private volatile List<String> beanDefinitionNames = new ArrayList<String>(256); 173 174 /** List of names of manually registered singletons, in registration order */ 175 private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16); 176 177 /** Cached array of bean definition names in case of frozen configuration */ 178 private volatile String[] frozenBeanDefinitionNames; 179 180 /** Whether bean definition metadata may be cached for all beans */ 181 private volatile boolean configurationFrozen; 182 183 184 /** 185 * Create a new DefaultListableBeanFactory. 186 */ 187 public DefaultListableBeanFactory() { 188 super(); 189 } 190 191 /** 192 * Create a new DefaultListableBeanFactory with the given parent. 193 * @param parentBeanFactory the parent BeanFactory 194 */ 195 public DefaultListableBeanFactory(BeanFactory parentBeanFactory) { 196 super(parentBeanFactory); 197 } 198 199 200 /** 201 * Specify an id for serialization purposes, allowing this BeanFactory to be 202 * deserialized from this id back into the BeanFactory object, if needed. 203 */ 204 public void setSerializationId(String serializationId) { 205 if (serializationId != null) { 206 serializableFactories.put(serializationId, new WeakReference<DefaultListableBeanFactory>(this)); 207 } 208 else if (this.serializationId != null) { 209 serializableFactories.remove(this.serializationId); 210 } 211 this.serializationId = serializationId; 212 } 213 214 /** 215 * Return an id for serialization purposes, if specified, allowing this BeanFactory 216 * to be deserialized from this id back into the BeanFactory object, if needed. 217 * @since 4.1.2 218 */ 219 public String getSerializationId() { 220 return this.serializationId; 221 } 222 223 /** 224 * Set whether it should be allowed to override bean definitions by registering 225 * a different definition with the same name, automatically replacing the former. 226 * If not, an exception will be thrown. This also applies to overriding aliases. 227 * <p>Default is "true". 228 * @see #registerBeanDefinition 229 */ 230 public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) { 231 this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding; 232 } 233 234 /** 235 * Return whether it should be allowed to override bean definitions by registering 236 * a different definition with the same name, automatically replacing the former. 237 * @since 4.1.2 238 */ 239 public boolean isAllowBeanDefinitionOverriding() { 240 return this.allowBeanDefinitionOverriding; 241 } 242 243 /** 244 * Set whether the factory is allowed to eagerly load bean classes 245 * even for bean definitions that are marked as "lazy-init". 246 * <p>Default is "true". Turn this flag off to suppress class loading 247 * for lazy-init beans unless such a bean is explicitly requested. 248 * In particular, by-type lookups will then simply ignore bean definitions 249 * without resolved class name, instead of loading the bean classes on 250 * demand just to perform a type check. 251 * @see AbstractBeanDefinition#setLazyInit 252 */ 253 public void setAllowEagerClassLoading(boolean allowEagerClassLoading) { 254 this.allowEagerClassLoading = allowEagerClassLoading; 255 } 256 257 /** 258 * Return whether the factory is allowed to eagerly load bean classes 259 * even for bean definitions that are marked as "lazy-init". 260 * @since 4.1.2 261 */ 262 public boolean isAllowEagerClassLoading() { 263 return this.allowEagerClassLoading; 264 } 265 266 /** 267 * Set a {@link java.util.Comparator} for dependency Lists and arrays. 268 * @since 4.0 269 * @see org.springframework.core.OrderComparator 270 * @see org.springframework.core.annotation.AnnotationAwareOrderComparator 271 */ 272 public void setDependencyComparator(Comparator<Object> dependencyComparator) { 273 this.dependencyComparator = dependencyComparator; 274 } 275 276 /** 277 * Return the dependency comparator for this BeanFactory (may be {@code null}. 278 * @since 4.0 279 */ 280 public Comparator<Object> getDependencyComparator() { 281 return this.dependencyComparator; 282 } 283 284 /** 285 * Set a custom autowire candidate resolver for this BeanFactory to use 286 * when deciding whether a bean definition should be considered as a 287 * candidate for autowiring. 288 */ 289 public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) { 290 Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null"); 291 if (autowireCandidateResolver instanceof BeanFactoryAware) { 292 if (System.getSecurityManager() != null) { 293 AccessController.doPrivileged(new PrivilegedAction<Object>() { 294 @Override 295 public Object run() { 296 ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(DefaultListableBeanFactory.this); 297 return null; 298 } 299 }, getAccessControlContext()); 300 } 301 else { 302 ((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this); 303 } 304 } 305 this.autowireCandidateResolver = autowireCandidateResolver; 306 } 307 308 /** 309 * Return the autowire candidate resolver for this BeanFactory (never {@code null}). 310 */ 311 public AutowireCandidateResolver getAutowireCandidateResolver() { 312 return this.autowireCandidateResolver; 313 } 314 315 316 @Override 317 public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { 318 super.copyConfigurationFrom(otherFactory); 319 if (otherFactory instanceof DefaultListableBeanFactory) { 320 DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory) otherFactory; 321 this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding; 322 this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading; 323 this.dependencyComparator = otherListableFactory.dependencyComparator; 324 // A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware... 325 setAutowireCandidateResolver( 326 BeanUtils.instantiateClass(otherListableFactory.getAutowireCandidateResolver().getClass())); 327 // Make resolvable dependencies (e.g. ResourceLoader) available here as well... 328 this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies); 329 } 330 } 331 332 333 //--------------------------------------------------------------------- 334 // Implementation of remaining BeanFactory methods 335 //--------------------------------------------------------------------- 336 337 @Override 338 public <T> T getBean(Class<T> requiredType) throws BeansException { 339 return getBean(requiredType, (Object[]) null); 340 } 341 342 @Override 343 public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException { 344 NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args); 345 if (namedBean != null) { 346 return namedBean.getBeanInstance(); 347 } 348 BeanFactory parent = getParentBeanFactory(); 349 if (parent != null) { 350 return parent.getBean(requiredType, args); 351 } 352 throw new NoSuchBeanDefinitionException(requiredType); 353 } 354 355 356 //--------------------------------------------------------------------- 357 // Implementation of ListableBeanFactory interface 358 //--------------------------------------------------------------------- 359 360 @Override 361 public boolean containsBeanDefinition(String beanName) { 362 Assert.notNull(beanName, "Bean name must not be null"); 363 return this.beanDefinitionMap.containsKey(beanName); 364 } 365 366 @Override 367 public int getBeanDefinitionCount() { 368 return this.beanDefinitionMap.size(); 369 } 370 371 @Override 372 public String[] getBeanDefinitionNames() { 373 String[] frozenNames = this.frozenBeanDefinitionNames; 374 if (frozenNames != null) { 375 return frozenNames.clone(); 376 } 377 else { 378 return StringUtils.toStringArray(this.beanDefinitionNames); 379 } 380 } 381 382 @Override 383 public String[] getBeanNamesForType(ResolvableType type) { 384 return doGetBeanNamesForType(type, true, true); 385 } 386 387 @Override 388 public String[] getBeanNamesForType(Class<?> type) { 389 return getBeanNamesForType(type, true, true); 390 } 391 392 @Override 393 public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) { 394 if (!isConfigurationFrozen() || type == null || !allowEagerInit) { 395 return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit); 396 } 397 Map<Class<?>, String[]> cache = 398 (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType); 399 String[] resolvedBeanNames = cache.get(type); 400 if (resolvedBeanNames != null) { 401 return resolvedBeanNames; 402 } 403 resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true); 404 if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) { 405 cache.put(type, resolvedBeanNames); 406 } 407 return resolvedBeanNames; 408 } 409 410 private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) { 411 List<String> result = new ArrayList<String>(); 412 413 // Check all bean definitions. 414 for (String beanName : this.beanDefinitionNames) { 415 // Only consider bean as eligible if the bean name 416 // is not defined as alias for some other bean. 417 if (!isAlias(beanName)) { 418 try { 419 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 420 // Only check bean definition if it is complete. 421 if (!mbd.isAbstract() && (allowEagerInit || 422 (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) && 423 !requiresEagerInitForType(mbd.getFactoryBeanName()))) { 424 // In case of FactoryBean, match object created by FactoryBean. 425 boolean isFactoryBean = isFactoryBean(beanName, mbd); 426 BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); 427 boolean matchFound = 428 (allowEagerInit || !isFactoryBean || 429 (dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) && 430 (includeNonSingletons || 431 (dbd != null ? mbd.isSingleton() : isSingleton(beanName))) && 432 isTypeMatch(beanName, type); 433 if (!matchFound && isFactoryBean) { 434 // In case of FactoryBean, try to match FactoryBean instance itself next. 435 beanName = FACTORY_BEAN_PREFIX + beanName; 436 matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type); 437 } 438 if (matchFound) { 439 result.add(beanName); 440 } 441 } 442 } 443 catch (CannotLoadBeanClassException ex) { 444 if (allowEagerInit) { 445 throw ex; 446 } 447 // Probably a class name with a placeholder: let's ignore it for type matching purposes. 448 if (logger.isDebugEnabled()) { 449 logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex); 450 } 451 onSuppressedException(ex); 452 } 453 catch (BeanDefinitionStoreException ex) { 454 if (allowEagerInit) { 455 throw ex; 456 } 457 // Probably some metadata with a placeholder: let's ignore it for type matching purposes. 458 if (logger.isDebugEnabled()) { 459 logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex); 460 } 461 onSuppressedException(ex); 462 } 463 } 464 } 465 466 // Check manually registered singletons too. 467 for (String beanName : this.manualSingletonNames) { 468 try { 469 // In case of FactoryBean, match object created by FactoryBean. 470 if (isFactoryBean(beanName)) { 471 if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) { 472 result.add(beanName); 473 // Match found for this bean: do not match FactoryBean itself anymore. 474 continue; 475 } 476 // In case of FactoryBean, try to match FactoryBean itself next. 477 beanName = FACTORY_BEAN_PREFIX + beanName; 478 } 479 // Match raw bean instance (might be raw FactoryBean). 480 if (isTypeMatch(beanName, type)) { 481 result.add(beanName); 482 } 483 } 484 catch (NoSuchBeanDefinitionException ex) { 485 // Shouldn't happen - probably a result of circular reference resolution... 486 if (logger.isDebugEnabled()) { 487 logger.debug("Failed to check manually registered singleton with name '" + beanName + "'", ex); 488 } 489 } 490 } 491 492 return StringUtils.toStringArray(result); 493 } 494 495 /** 496 * Check whether the specified bean would need to be eagerly initialized 497 * in order to determine its type. 498 * @param factoryBeanName a factory-bean reference that the bean definition 499 * defines a factory method for 500 * @return whether eager initialization is necessary 501 */ 502 private boolean requiresEagerInitForType(String factoryBeanName) { 503 return (factoryBeanName != null && isFactoryBean(factoryBeanName) && !containsSingleton(factoryBeanName)); 504 } 505 506 @Override 507 public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException { 508 return getBeansOfType(type, true, true); 509 } 510 511 @Override 512 public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) 513 throws BeansException { 514 515 String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit); 516 Map<String, T> result = new LinkedHashMap<String, T>(beanNames.length); 517 for (String beanName : beanNames) { 518 try { 519 result.put(beanName, getBean(beanName, type)); 520 } 521 catch (BeanCreationException ex) { 522 Throwable rootCause = ex.getMostSpecificCause(); 523 if (rootCause instanceof BeanCurrentlyInCreationException) { 524 BeanCreationException bce = (BeanCreationException) rootCause; 525 if (isCurrentlyInCreation(bce.getBeanName())) { 526 if (logger.isDebugEnabled()) { 527 logger.debug("Ignoring match to currently created bean '" + beanName + "': " + 528 ex.getMessage()); 529 } 530 onSuppressedException(ex); 531 // Ignore: indicates a circular reference when autowiring constructors. 532 // We want to find matches other than the currently created bean itself. 533 continue; 534 } 535 } 536 throw ex; 537 } 538 } 539 return result; 540 } 541 542 @Override 543 public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) { 544 List<String> result = new ArrayList<String>(); 545 for (String beanName : this.beanDefinitionNames) { 546 BeanDefinition beanDefinition = getBeanDefinition(beanName); 547 if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) { 548 result.add(beanName); 549 } 550 } 551 for (String beanName : this.manualSingletonNames) { 552 if (!result.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) { 553 result.add(beanName); 554 } 555 } 556 return StringUtils.toStringArray(result); 557 } 558 559 @Override 560 public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) { 561 String[] beanNames = getBeanNamesForAnnotation(annotationType); 562 Map<String, Object> result = new LinkedHashMap<String, Object>(beanNames.length); 563 for (String beanName : beanNames) { 564 result.put(beanName, getBean(beanName)); 565 } 566 return result; 567 } 568 569 @Override 570 public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) 571 throws NoSuchBeanDefinitionException { 572 573 A ann = null; 574 Class<?> beanType = getType(beanName); 575 if (beanType != null) { 576 ann = AnnotationUtils.findAnnotation(beanType, annotationType); 577 } 578 if (ann == null && containsBeanDefinition(beanName)) { 579 // Check raw bean class, e.g. in case of a proxy. 580 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 581 if (bd.hasBeanClass()) { 582 Class<?> beanClass = bd.getBeanClass(); 583 if (beanClass != beanType) { 584 ann = AnnotationUtils.findAnnotation(beanClass, annotationType); 585 } 586 } 587 } 588 return ann; 589 } 590 591 592 //--------------------------------------------------------------------- 593 // Implementation of ConfigurableListableBeanFactory interface 594 //--------------------------------------------------------------------- 595 596 @Override 597 public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) { 598 Assert.notNull(dependencyType, "Dependency type must not be null"); 599 if (autowiredValue != null) { 600 if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) { 601 throw new IllegalArgumentException("Value [" + autowiredValue + 602 "] does not implement specified dependency type [" + dependencyType.getName() + "]"); 603 } 604 this.resolvableDependencies.put(dependencyType, autowiredValue); 605 } 606 } 607 608 @Override 609 public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) 610 throws NoSuchBeanDefinitionException { 611 612 return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver()); 613 } 614 615 /** 616 * Determine whether the specified bean definition qualifies as an autowire candidate, 617 * to be injected into other beans which declare a dependency of matching type. 618 * @param beanName the name of the bean definition to check 619 * @param descriptor the descriptor of the dependency to resolve 620 * @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm 621 * @return whether the bean should be considered as autowire candidate 622 */ 623 protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) 624 throws NoSuchBeanDefinitionException { 625 626 String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); 627 if (containsBeanDefinition(beanDefinitionName)) { 628 return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver); 629 } 630 else if (containsSingleton(beanName)) { 631 return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver); 632 } 633 634 BeanFactory parent = getParentBeanFactory(); 635 if (parent instanceof DefaultListableBeanFactory) { 636 // No bean definition found in this factory -> delegate to parent. 637 return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver); 638 } 639 else if (parent instanceof ConfigurableListableBeanFactory) { 640 // If no DefaultListableBeanFactory, can't pass the resolver along. 641 return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor); 642 } 643 else { 644 return true; 645 } 646 } 647 648 /** 649 * Determine whether the specified bean definition qualifies as an autowire candidate, 650 * to be injected into other beans which declare a dependency of matching type. 651 * @param beanName the name of the bean definition to check 652 * @param mbd the merged bean definition to check 653 * @param descriptor the descriptor of the dependency to resolve 654 * @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm 655 * @return whether the bean should be considered as autowire candidate 656 */ 657 protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, 658 DependencyDescriptor descriptor, AutowireCandidateResolver resolver) { 659 660 String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); 661 resolveBeanClass(mbd, beanDefinitionName); 662 if (mbd.isFactoryMethodUnique) { 663 boolean resolve; 664 synchronized (mbd.constructorArgumentLock) { 665 resolve = (mbd.resolvedConstructorOrFactoryMethod == null); 666 } 667 if (resolve) { 668 new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd); 669 } 670 } 671 return resolver.isAutowireCandidate( 672 new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor); 673 } 674 675 @Override 676 public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { 677 BeanDefinition bd = this.beanDefinitionMap.get(beanName); 678 if (bd == null) { 679 if (logger.isTraceEnabled()) { 680 logger.trace("No bean named '" + beanName + "' found in " + this); 681 } 682 throw new NoSuchBeanDefinitionException(beanName); 683 } 684 return bd; 685 } 686 687 @Override 688 public Iterator<String> getBeanNamesIterator() { 689 CompositeIterator<String> iterator = new CompositeIterator<String>(); 690 iterator.add(this.beanDefinitionNames.iterator()); 691 iterator.add(this.manualSingletonNames.iterator()); 692 return iterator; 693 } 694 695 @Override 696 public void clearMetadataCache() { 697 super.clearMetadataCache(); 698 clearByTypeCache(); 699 } 700 701 @Override 702 public void freezeConfiguration() { 703 this.configurationFrozen = true; 704 this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames); 705 } 706 707 @Override 708 public boolean isConfigurationFrozen() { 709 return this.configurationFrozen; 710 } 711 712 /** 713 * Considers all beans as eligible for metadata caching 714 * if the factory's configuration has been marked as frozen. 715 * @see #freezeConfiguration() 716 */ 717 @Override 718 protected boolean isBeanEligibleForMetadataCaching(String beanName) { 719 return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName)); 720 } 721 722 @Override 723 public void preInstantiateSingletons() throws BeansException { 724 if (logger.isDebugEnabled()) { 725 logger.debug("Pre-instantiating singletons in " + this); 726 } 727 728 // Iterate over a copy to allow for init methods which in turn register new bean definitions. 729 // While this may not be part of the regular factory bootstrap, it does otherwise work fine. 730 List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); 731 732 // Trigger initialization of all non-lazy singleton beans... 733 for (String beanName : beanNames) { 734 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 735 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 736 if (isFactoryBean(beanName)) { 737 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); 738 boolean isEagerInit; 739 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 740 isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 741 @Override 742 public Boolean run() { 743 return ((SmartFactoryBean<?>) factory).isEagerInit(); 744 } 745 }, getAccessControlContext()); 746 } 747 else { 748 isEagerInit = (factory instanceof SmartFactoryBean && 749 ((SmartFactoryBean<?>) factory).isEagerInit()); 750 } 751 if (isEagerInit) { 752 getBean(beanName); 753 } 754 } 755 else { 756 getBean(beanName); 757 } 758 } 759 } 760 761 // Trigger post-initialization callback for all applicable beans... 762 for (String beanName : beanNames) { 763 Object singletonInstance = getSingleton(beanName); 764 if (singletonInstance instanceof SmartInitializingSingleton) { 765 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 766 if (System.getSecurityManager() != null) { 767 AccessController.doPrivileged(new PrivilegedAction<Object>() { 768 @Override 769 public Object run() { 770 smartSingleton.afterSingletonsInstantiated(); 771 return null; 772 } 773 }, getAccessControlContext()); 774 } 775 else { 776 smartSingleton.afterSingletonsInstantiated(); 777 } 778 } 779 } 780 } 781 782 783 //--------------------------------------------------------------------- 784 // Implementation of BeanDefinitionRegistry interface 785 //--------------------------------------------------------------------- 786 787 @Override 788 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 789 throws BeanDefinitionStoreException { 790 791 Assert.hasText(beanName, "Bean name must not be empty"); 792 Assert.notNull(beanDefinition, "BeanDefinition must not be null"); 793 794 if (beanDefinition instanceof AbstractBeanDefinition) { 795 try { 796 ((AbstractBeanDefinition) beanDefinition).validate(); 797 } 798 catch (BeanDefinitionValidationException ex) { 799 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 800 "Validation of bean definition failed", ex); 801 } 802 } 803 804 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); 805 if (existingDefinition != null) { 806 if (!isAllowBeanDefinitionOverriding()) { 807 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 808 "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + 809 "': There is already [" + existingDefinition + "] bound."); 810 } 811 else if (existingDefinition.getRole() < beanDefinition.getRole()) { 812 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE 813 if (logger.isWarnEnabled()) { 814 logger.warn("Overriding user-defined bean definition for bean '" + beanName + 815 "' with a framework-generated bean definition: replacing [" + 816 existingDefinition + "] with [" + beanDefinition + "]"); 817 } 818 } 819 else if (!beanDefinition.equals(existingDefinition)) { 820 if (logger.isInfoEnabled()) { 821 logger.info("Overriding bean definition for bean '" + beanName + 822 "' with a different definition: replacing [" + existingDefinition + 823 "] with [" + beanDefinition + "]"); 824 } 825 } 826 else { 827 if (logger.isDebugEnabled()) { 828 logger.debug("Overriding bean definition for bean '" + beanName + 829 "' with an equivalent definition: replacing [" + existingDefinition + 830 "] with [" + beanDefinition + "]"); 831 } 832 } 833 this.beanDefinitionMap.put(beanName, beanDefinition); 834 } 835 else { 836 if (hasBeanCreationStarted()) { 837 // Cannot modify startup-time collection elements anymore (for stable iteration) 838 synchronized (this.beanDefinitionMap) { 839 this.beanDefinitionMap.put(beanName, beanDefinition); 840 List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); 841 updatedDefinitions.addAll(this.beanDefinitionNames); 842 updatedDefinitions.add(beanName); 843 this.beanDefinitionNames = updatedDefinitions; 844 if (this.manualSingletonNames.contains(beanName)) { 845 Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); 846 updatedSingletons.remove(beanName); 847 this.manualSingletonNames = updatedSingletons; 848 } 849 } 850 } 851 else { 852 // Still in startup registration phase 853 this.beanDefinitionMap.put(beanName, beanDefinition); 854 this.beanDefinitionNames.add(beanName); 855 this.manualSingletonNames.remove(beanName); 856 } 857 this.frozenBeanDefinitionNames = null; 858 } 859 860 if (existingDefinition != null || containsSingleton(beanName)) { 861 resetBeanDefinition(beanName); 862 } 863 else if (isConfigurationFrozen()) { 864 clearByTypeCache(); 865 } 866 } 867 868 @Override 869 public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { 870 Assert.hasText(beanName, "'beanName' must not be empty"); 871 872 BeanDefinition bd = this.beanDefinitionMap.remove(beanName); 873 if (bd == null) { 874 if (logger.isTraceEnabled()) { 875 logger.trace("No bean named '" + beanName + "' found in " + this); 876 } 877 throw new NoSuchBeanDefinitionException(beanName); 878 } 879 880 if (hasBeanCreationStarted()) { 881 // Cannot modify startup-time collection elements anymore (for stable iteration) 882 synchronized (this.beanDefinitionMap) { 883 List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames); 884 updatedDefinitions.remove(beanName); 885 this.beanDefinitionNames = updatedDefinitions; 886 } 887 } 888 else { 889 // Still in startup registration phase 890 this.beanDefinitionNames.remove(beanName); 891 } 892 this.frozenBeanDefinitionNames = null; 893 894 resetBeanDefinition(beanName); 895 } 896 897 /** 898 * Reset all bean definition caches for the given bean, 899 * including the caches of beans that are derived from it. 900 * @param beanName the name of the bean to reset 901 */ 902 protected void resetBeanDefinition(String beanName) { 903 // Remove the merged bean definition for the given bean, if already created. 904 clearMergedBeanDefinition(beanName); 905 906 // Remove corresponding bean from singleton cache, if any. Shouldn't usually 907 // be necessary, rather just meant for overriding a context's default beans 908 // (e.g. the default StaticMessageSource in a StaticApplicationContext). 909 destroySingleton(beanName); 910 911 // Reset all bean definitions that have the given bean as parent (recursively). 912 for (String bdName : this.beanDefinitionNames) { 913 if (!beanName.equals(bdName)) { 914 BeanDefinition bd = this.beanDefinitionMap.get(bdName); 915 if (bd != null && beanName.equals(bd.getParentName())) { 916 resetBeanDefinition(bdName); 917 } 918 } 919 } 920 } 921 922 /** 923 * Only allows alias overriding if bean definition overriding is allowed. 924 */ 925 @Override 926 protected boolean allowAliasOverriding() { 927 return isAllowBeanDefinitionOverriding(); 928 } 929 930 @Override 931 public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { 932 super.registerSingleton(beanName, singletonObject); 933 934 if (hasBeanCreationStarted()) { 935 // Cannot modify startup-time collection elements anymore (for stable iteration) 936 synchronized (this.beanDefinitionMap) { 937 if (!this.beanDefinitionMap.containsKey(beanName)) { 938 Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames.size() + 1); 939 updatedSingletons.addAll(this.manualSingletonNames); 940 updatedSingletons.add(beanName); 941 this.manualSingletonNames = updatedSingletons; 942 } 943 } 944 } 945 else { 946 // Still in startup registration phase 947 if (!this.beanDefinitionMap.containsKey(beanName)) { 948 this.manualSingletonNames.add(beanName); 949 } 950 } 951 952 clearByTypeCache(); 953 } 954 955 @Override 956 public void destroySingleton(String beanName) { 957 super.destroySingleton(beanName); 958 this.manualSingletonNames.remove(beanName); 959 clearByTypeCache(); 960 } 961 962 @Override 963 public void destroySingletons() { 964 super.destroySingletons(); 965 this.manualSingletonNames.clear(); 966 clearByTypeCache(); 967 } 968 969 /** 970 * Remove any assumptions about by-type mappings. 971 */ 972 private void clearByTypeCache() { 973 this.allBeanNamesByType.clear(); 974 this.singletonBeanNamesByType.clear(); 975 } 976 977 978 //--------------------------------------------------------------------- 979 // Dependency resolution functionality 980 //--------------------------------------------------------------------- 981 982 @Override 983 public <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException { 984 NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, (Object[]) null); 985 if (namedBean != null) { 986 return namedBean; 987 } 988 BeanFactory parent = getParentBeanFactory(); 989 if (parent instanceof AutowireCapableBeanFactory) { 990 return ((AutowireCapableBeanFactory) parent).resolveNamedBean(requiredType); 991 } 992 throw new NoSuchBeanDefinitionException(requiredType); 993 } 994 995 @SuppressWarnings("unchecked") 996 private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException { 997 Assert.notNull(requiredType, "Required type must not be null"); 998 String[] candidateNames = getBeanNamesForType(requiredType); 999 1000 if (candidateNames.length > 1) { 1001 List<String> autowireCandidates = new ArrayList<String>(candidateNames.length); 1002 for (String beanName : candidateNames) { 1003 if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) { 1004 autowireCandidates.add(beanName); 1005 } 1006 } 1007 if (!autowireCandidates.isEmpty()) { 1008 candidateNames = StringUtils.toStringArray(autowireCandidates); 1009 } 1010 } 1011 1012 if (candidateNames.length == 1) { 1013 String beanName = candidateNames[0]; 1014 return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args)); 1015 } 1016 else if (candidateNames.length > 1) { 1017 Map<String, Object> candidates = new LinkedHashMap<String, Object>(candidateNames.length); 1018 for (String beanName : candidateNames) { 1019 if (containsSingleton(beanName)) { 1020 candidates.put(beanName, getBean(beanName, requiredType, args)); 1021 } 1022 else { 1023 candidates.put(beanName, getType(beanName)); 1024 } 1025 } 1026 String candidateName = determinePrimaryCandidate(candidates, requiredType); 1027 if (candidateName == null) { 1028 candidateName = determineHighestPriorityCandidate(candidates, requiredType); 1029 } 1030 if (candidateName != null) { 1031 Object beanInstance = candidates.get(candidateName); 1032 if (beanInstance instanceof Class) { 1033 beanInstance = getBean(candidateName, requiredType, args); 1034 } 1035 return new NamedBeanHolder<T>(candidateName, (T) beanInstance); 1036 } 1037 throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); 1038 } 1039 1040 return null; 1041 } 1042 1043 @Override 1044 public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, 1045 Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { 1046 1047 descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); 1048 if (javaUtilOptionalClass == descriptor.getDependencyType()) { 1049 return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName); 1050 } 1051 else if (ObjectFactory.class == descriptor.getDependencyType() || 1052 ObjectProvider.class == descriptor.getDependencyType()) { 1053 return new DependencyObjectProvider(descriptor, requestingBeanName); 1054 } 1055 else if (javaxInjectProviderClass == descriptor.getDependencyType()) { 1056 return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName); 1057 } 1058 else { 1059 Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( 1060 descriptor, requestingBeanName); 1061 if (result == null) { 1062 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); 1063 } 1064 return result; 1065 } 1066 } 1067 1068 public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, 1069 Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { 1070 1071 InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); 1072 try { 1073 Object shortcut = descriptor.resolveShortcut(this); 1074 if (shortcut != null) { 1075 return shortcut; 1076 } 1077 1078 Class<?> type = descriptor.getDependencyType(); 1079 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); 1080 if (value != null) { 1081 if (value instanceof String) { 1082 String strVal = resolveEmbeddedValue((String) value); 1083 BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); 1084 value = evaluateBeanDefinitionString(strVal, bd); 1085 } 1086 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); 1087 return (descriptor.getField() != null ? 1088 converter.convertIfNecessary(value, type, descriptor.getField()) : 1089 converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); 1090 } 1091 1092 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); 1093 if (multipleBeans != null) { 1094 return multipleBeans; 1095 } 1096 1097 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); 1098 if (matchingBeans.isEmpty()) { 1099 if (isRequired(descriptor)) { 1100 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); 1101 } 1102 return null; 1103 } 1104 1105 String autowiredBeanName; 1106 Object instanceCandidate; 1107 1108 if (matchingBeans.size() > 1) { 1109 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); 1110 if (autowiredBeanName == null) { 1111 if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { 1112 return descriptor.resolveNotUnique(type, matchingBeans); 1113 } 1114 else { 1115 // In case of an optional Collection/Map, silently ignore a non-unique case: 1116 // possibly it was meant to be an empty collection of multiple regular beans 1117 // (before 4.3 in particular when we didn't even look for collection beans). 1118 return null; 1119 } 1120 } 1121 instanceCandidate = matchingBeans.get(autowiredBeanName); 1122 } 1123 else { 1124 // We have exactly one match. 1125 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); 1126 autowiredBeanName = entry.getKey(); 1127 instanceCandidate = entry.getValue(); 1128 } 1129 1130 if (autowiredBeanNames != null) { 1131 autowiredBeanNames.add(autowiredBeanName); 1132 } 1133 return (instanceCandidate instanceof Class ? 1134 descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate); 1135 } 1136 finally { 1137 ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); 1138 } 1139 } 1140 1141 private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName, 1142 Set<String> autowiredBeanNames, TypeConverter typeConverter) { 1143 1144 Class<?> type = descriptor.getDependencyType(); 1145 if (type.isArray()) { 1146 Class<?> componentType = type.getComponentType(); 1147 ResolvableType resolvableType = descriptor.getResolvableType(); 1148 Class<?> resolvedArrayType = resolvableType.resolve(); 1149 if (resolvedArrayType != null && resolvedArrayType != type) { 1150 type = resolvedArrayType; 1151 componentType = resolvableType.getComponentType().resolve(); 1152 } 1153 if (componentType == null) { 1154 return null; 1155 } 1156 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, 1157 new MultiElementDescriptor(descriptor)); 1158 if (matchingBeans.isEmpty()) { 1159 return null; 1160 } 1161 if (autowiredBeanNames != null) { 1162 autowiredBeanNames.addAll(matchingBeans.keySet()); 1163 } 1164 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); 1165 Object result = converter.convertIfNecessary(matchingBeans.values(), type); 1166 if (getDependencyComparator() != null && result instanceof Object[]) { 1167 Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans)); 1168 } 1169 return result; 1170 } 1171 else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { 1172 Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); 1173 if (elementType == null) { 1174 return null; 1175 } 1176 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, 1177 new MultiElementDescriptor(descriptor)); 1178 if (matchingBeans.isEmpty()) { 1179 return null; 1180 } 1181 if (autowiredBeanNames != null) { 1182 autowiredBeanNames.addAll(matchingBeans.keySet()); 1183 } 1184 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); 1185 Object result = converter.convertIfNecessary(matchingBeans.values(), type); 1186 if (getDependencyComparator() != null && result instanceof List) { 1187 Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans)); 1188 } 1189 return result; 1190 } 1191 else if (Map.class == type) { 1192 ResolvableType mapType = descriptor.getResolvableType().asMap(); 1193 Class<?> keyType = mapType.resolveGeneric(0); 1194 if (String.class != keyType) { 1195 return null; 1196 } 1197 Class<?> valueType = mapType.resolveGeneric(1); 1198 if (valueType == null) { 1199 return null; 1200 } 1201 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, 1202 new MultiElementDescriptor(descriptor)); 1203 if (matchingBeans.isEmpty()) { 1204 return null; 1205 } 1206 if (autowiredBeanNames != null) { 1207 autowiredBeanNames.addAll(matchingBeans.keySet()); 1208 } 1209 return matchingBeans; 1210 } 1211 else { 1212 return null; 1213 } 1214 } 1215 1216 private boolean isRequired(DependencyDescriptor descriptor) { 1217 AutowireCandidateResolver resolver = getAutowireCandidateResolver(); 1218 return (resolver instanceof SimpleAutowireCandidateResolver ? 1219 ((SimpleAutowireCandidateResolver) resolver).isRequired(descriptor) : 1220 descriptor.isRequired()); 1221 } 1222 1223 private boolean indicatesMultipleBeans(Class<?> type) { 1224 return (type.isArray() || (type.isInterface() && 1225 (Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type)))); 1226 } 1227 1228 private Comparator<Object> adaptDependencyComparator(Map<String, Object> matchingBeans) { 1229 Comparator<Object> comparator = getDependencyComparator(); 1230 if (comparator instanceof OrderComparator) { 1231 return ((OrderComparator) comparator).withSourceProvider( 1232 createFactoryAwareOrderSourceProvider(matchingBeans)); 1233 } 1234 else { 1235 return comparator; 1236 } 1237 } 1238 1239 private OrderComparator.OrderSourceProvider createFactoryAwareOrderSourceProvider(Map<String, Object> beans) { 1240 IdentityHashMap<Object, String> instancesToBeanNames = new IdentityHashMap<Object, String>(); 1241 for (Map.Entry<String, Object> entry : beans.entrySet()) { 1242 instancesToBeanNames.put(entry.getValue(), entry.getKey()); 1243 } 1244 return new FactoryAwareOrderSourceProvider(instancesToBeanNames); 1245 } 1246 1247 /** 1248 * Find bean instances that match the required type. 1249 * Called during autowiring for the specified bean. 1250 * @param beanName the name of the bean that is about to be wired 1251 * @param requiredType the actual type of bean to look for 1252 * (may be an array component type or collection element type) 1253 * @param descriptor the descriptor of the dependency to resolve 1254 * @return a Map of candidate names and candidate instances that match 1255 * the required type (never {@code null}) 1256 * @throws BeansException in case of errors 1257 * @see #autowireByType 1258 * @see #autowireConstructor 1259 */ 1260 protected Map<String, Object> findAutowireCandidates( 1261 String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { 1262 1263 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( 1264 this, requiredType, true, descriptor.isEager()); 1265 Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length); 1266 for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { 1267 if (autowiringType.isAssignableFrom(requiredType)) { 1268 Object autowiringValue = this.resolvableDependencies.get(autowiringType); 1269 autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); 1270 if (requiredType.isInstance(autowiringValue)) { 1271 result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); 1272 break; 1273 } 1274 } 1275 } 1276 for (String candidate : candidateNames) { 1277 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { 1278 addCandidateEntry(result, candidate, descriptor, requiredType); 1279 } 1280 } 1281 if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { 1282 // Consider fallback matches if the first pass failed to find anything... 1283 DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); 1284 for (String candidate : candidateNames) { 1285 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { 1286 addCandidateEntry(result, candidate, descriptor, requiredType); 1287 } 1288 } 1289 if (result.isEmpty()) { 1290 // Consider self references as a final pass... 1291 // but in the case of a dependency collection, not the very same bean itself. 1292 for (String candidate : candidateNames) { 1293 if (isSelfReference(beanName, candidate) && 1294 (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && 1295 isAutowireCandidate(candidate, fallbackDescriptor)) { 1296 addCandidateEntry(result, candidate, descriptor, requiredType); 1297 } 1298 } 1299 } 1300 } 1301 return result; 1302 } 1303 1304 /** 1305 * Add an entry to the candidate map: a bean instance if available or just the resolved 1306 * type, preventing early bean initialization ahead of primary candidate selection. 1307 */ 1308 private void addCandidateEntry(Map<String, Object> candidates, String candidateName, 1309 DependencyDescriptor descriptor, Class<?> requiredType) { 1310 1311 if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { 1312 candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this)); 1313 } 1314 else { 1315 candidates.put(candidateName, getType(candidateName)); 1316 } 1317 } 1318 1319 /** 1320 * Determine the autowire candidate in the given set of beans. 1321 * <p>Looks for {@code @Primary} and {@code @Priority} (in that order). 1322 * @param candidates a Map of candidate names and candidate instances 1323 * that match the required type, as returned by {@link #findAutowireCandidates} 1324 * @param descriptor the target dependency to match against 1325 * @return the name of the autowire candidate, or {@code null} if none found 1326 */ 1327 protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) { 1328 Class<?> requiredType = descriptor.getDependencyType(); 1329 String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); 1330 if (primaryCandidate != null) { 1331 return primaryCandidate; 1332 } 1333 String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType); 1334 if (priorityCandidate != null) { 1335 return priorityCandidate; 1336 } 1337 // Fallback 1338 for (Map.Entry<String, Object> entry : candidates.entrySet()) { 1339 String candidateName = entry.getKey(); 1340 Object beanInstance = entry.getValue(); 1341 if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || 1342 matchesBeanName(candidateName, descriptor.getDependencyName())) { 1343 return candidateName; 1344 } 1345 } 1346 return null; 1347 } 1348 1349 /** 1350 * Determine the primary candidate in the given set of beans. 1351 * @param candidates a Map of candidate names and candidate instances 1352 * (or candidate classes if not created yet) that match the required type 1353 * @param requiredType the target dependency type to match against 1354 * @return the name of the primary candidate, or {@code null} if none found 1355 * @see #isPrimary(String, Object) 1356 */ 1357 protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) { 1358 String primaryBeanName = null; 1359 for (Map.Entry<String, Object> entry : candidates.entrySet()) { 1360 String candidateBeanName = entry.getKey(); 1361 Object beanInstance = entry.getValue(); 1362 if (isPrimary(candidateBeanName, beanInstance)) { 1363 if (primaryBeanName != null) { 1364 boolean candidateLocal = containsBeanDefinition(candidateBeanName); 1365 boolean primaryLocal = containsBeanDefinition(primaryBeanName); 1366 if (candidateLocal && primaryLocal) { 1367 throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), 1368 "more than one 'primary' bean found among candidates: " + candidates.keySet()); 1369 } 1370 else if (candidateLocal) { 1371 primaryBeanName = candidateBeanName; 1372 } 1373 } 1374 else { 1375 primaryBeanName = candidateBeanName; 1376 } 1377 } 1378 } 1379 return primaryBeanName; 1380 } 1381 1382 /** 1383 * Determine the candidate with the highest priority in the given set of beans. 1384 * <p>Based on {@code @javax.annotation.Priority}. As defined by the related 1385 * {@link org.springframework.core.Ordered} interface, the lowest value has 1386 * the highest priority. 1387 * @param candidates a Map of candidate names and candidate instances 1388 * (or candidate classes if not created yet) that match the required type 1389 * @param requiredType the target dependency type to match against 1390 * @return the name of the candidate with the highest priority, 1391 * or {@code null} if none found 1392 * @see #getPriority(Object) 1393 */ 1394 protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) { 1395 String highestPriorityBeanName = null; 1396 Integer highestPriority = null; 1397 for (Map.Entry<String, Object> entry : candidates.entrySet()) { 1398 String candidateBeanName = entry.getKey(); 1399 Object beanInstance = entry.getValue(); 1400 Integer candidatePriority = getPriority(beanInstance); 1401 if (candidatePriority != null) { 1402 if (highestPriorityBeanName != null) { 1403 if (candidatePriority.equals(highestPriority)) { 1404 throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), 1405 "Multiple beans found with the same priority ('" + highestPriority + 1406 "') among candidates: " + candidates.keySet()); 1407 } 1408 else if (candidatePriority < highestPriority) { 1409 highestPriorityBeanName = candidateBeanName; 1410 highestPriority = candidatePriority; 1411 } 1412 } 1413 else { 1414 highestPriorityBeanName = candidateBeanName; 1415 highestPriority = candidatePriority; 1416 } 1417 } 1418 } 1419 return highestPriorityBeanName; 1420 } 1421 1422 /** 1423 * Return whether the bean definition for the given bean name has been 1424 * marked as a primary bean. 1425 * @param beanName the name of the bean 1426 * @param beanInstance the corresponding bean instance (can be null) 1427 * @return whether the given bean qualifies as primary 1428 */ 1429 protected boolean isPrimary(String beanName, Object beanInstance) { 1430 if (containsBeanDefinition(beanName)) { 1431 return getMergedLocalBeanDefinition(beanName).isPrimary(); 1432 } 1433 BeanFactory parent = getParentBeanFactory(); 1434 return (parent instanceof DefaultListableBeanFactory && 1435 ((DefaultListableBeanFactory) parent).isPrimary(beanName, beanInstance)); 1436 } 1437 1438 /** 1439 * Return the priority assigned for the given bean instance by 1440 * the {@code javax.annotation.Priority} annotation. 1441 * <p>The default implementation delegates to the specified 1442 * {@link #setDependencyComparator dependency comparator}, checking its 1443 * {@link OrderComparator#getPriority method} if it is an extension of 1444 * Spring's common {@link OrderComparator} - typically, an 1445 * {@link org.springframework.core.annotation.AnnotationAwareOrderComparator}. 1446 * If no such comparator is present, this implementation returns {@code null}. 1447 * @param beanInstance the bean instance to check (can be {@code null}) 1448 * @return the priority assigned to that bean or {@code null} if none is set 1449 */ 1450 protected Integer getPriority(Object beanInstance) { 1451 Comparator<Object> comparator = getDependencyComparator(); 1452 if (comparator instanceof OrderComparator) { 1453 return ((OrderComparator) comparator).getPriority(beanInstance); 1454 } 1455 return null; 1456 } 1457 1458 /** 1459 * Determine whether the given candidate name matches the bean name or the aliases 1460 * stored in this bean definition. 1461 */ 1462 protected boolean matchesBeanName(String beanName, String candidateName) { 1463 return (candidateName != null && 1464 (candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName))); 1465 } 1466 1467 /** 1468 * Determine whether the given beanName/candidateName pair indicates a self reference, 1469 * i.e. whether the candidate points back to the original bean or to a factory method 1470 * on the original bean. 1471 */ 1472 private boolean isSelfReference(String beanName, String candidateName) { 1473 return (beanName != null && candidateName != null && 1474 (beanName.equals(candidateName) || (containsBeanDefinition(candidateName) && 1475 beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName())))); 1476 } 1477 1478 /** 1479 * Raise a NoSuchBeanDefinitionException or BeanNotOfRequiredTypeException 1480 * for an unresolvable dependency. 1481 */ 1482 private void raiseNoMatchingBeanFound( 1483 Class<?> type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException { 1484 1485 checkBeanNotOfRequiredType(type, descriptor); 1486 1487 throw new NoSuchBeanDefinitionException(resolvableType, 1488 "expected at least 1 bean which qualifies as autowire candidate. " + 1489 "Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations())); 1490 } 1491 1492 /** 1493 * Raise a BeanNotOfRequiredTypeException for an unresolvable dependency, if applicable, 1494 * i.e. if the target type of the bean would match but an exposed proxy doesn't. 1495 */ 1496 private void checkBeanNotOfRequiredType(Class<?> type, DependencyDescriptor descriptor) { 1497 for (String beanName : this.beanDefinitionNames) { 1498 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 1499 Class<?> targetType = mbd.getTargetType(); 1500 if (targetType != null && type.isAssignableFrom(targetType) && 1501 isAutowireCandidate(beanName, mbd, descriptor, getAutowireCandidateResolver())) { 1502 // Probably a proxy interfering with target type match -> throw meaningful exception. 1503 Object beanInstance = getSingleton(beanName, false); 1504 Class<?> beanType = (beanInstance != null ? beanInstance.getClass() : predictBeanType(beanName, mbd)); 1505 if (!type.isAssignableFrom((beanType))) { 1506 throw new BeanNotOfRequiredTypeException(beanName, type, beanType); 1507 } 1508 } 1509 } 1510 1511 BeanFactory parent = getParentBeanFactory(); 1512 if (parent instanceof DefaultListableBeanFactory) { 1513 ((DefaultListableBeanFactory) parent).checkBeanNotOfRequiredType(type, descriptor); 1514 } 1515 } 1516 1517 1518 @Override 1519 public String toString() { 1520 StringBuilder sb = new StringBuilder(ObjectUtils.identityToString(this)); 1521 sb.append(": defining beans ["); 1522 sb.append(StringUtils.collectionToCommaDelimitedString(this.beanDefinitionNames)); 1523 sb.append("]; "); 1524 BeanFactory parent = getParentBeanFactory(); 1525 if (parent == null) { 1526 sb.append("root of factory hierarchy"); 1527 } 1528 else { 1529 sb.append("parent: ").append(ObjectUtils.identityToString(parent)); 1530 } 1531 return sb.toString(); 1532 } 1533 1534 1535 //--------------------------------------------------------------------- 1536 // Serialization support 1537 //--------------------------------------------------------------------- 1538 1539 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 1540 throw new NotSerializableException("DefaultListableBeanFactory itself is not deserializable - " + 1541 "just a SerializedBeanFactoryReference is"); 1542 } 1543 1544 protected Object writeReplace() throws ObjectStreamException { 1545 if (this.serializationId != null) { 1546 return new SerializedBeanFactoryReference(this.serializationId); 1547 } 1548 else { 1549 throw new NotSerializableException("DefaultListableBeanFactory has no serialization id"); 1550 } 1551 } 1552 1553 1554 /** 1555 * Minimal id reference to the factory. 1556 * Resolved to the actual factory instance on deserialization. 1557 */ 1558 private static class SerializedBeanFactoryReference implements Serializable { 1559 1560 private final String id; 1561 1562 public SerializedBeanFactoryReference(String id) { 1563 this.id = id; 1564 } 1565 1566 private Object readResolve() { 1567 Reference<?> ref = serializableFactories.get(this.id); 1568 if (ref != null) { 1569 Object result = ref.get(); 1570 if (result != null) { 1571 return result; 1572 } 1573 } 1574 // Lenient fallback: dummy factory in case of original factory not found... 1575 DefaultListableBeanFactory dummyFactory = new DefaultListableBeanFactory(); 1576 dummyFactory.serializationId = this.id; 1577 return dummyFactory; 1578 } 1579 } 1580 1581 1582 /** 1583 * A dependency descriptor marker for nested elements. 1584 */ 1585 private static class NestedDependencyDescriptor extends DependencyDescriptor { 1586 1587 public NestedDependencyDescriptor(DependencyDescriptor original) { 1588 super(original); 1589 increaseNestingLevel(); 1590 } 1591 } 1592 1593 1594 /** 1595 * A dependency descriptor for a multi-element declaration with nested elements. 1596 */ 1597 private static class MultiElementDescriptor extends NestedDependencyDescriptor { 1598 1599 public MultiElementDescriptor(DependencyDescriptor original) { 1600 super(original); 1601 } 1602 } 1603 1604 1605 /** 1606 * Separate inner class for avoiding a hard dependency on the {@code javax.inject} API. 1607 */ 1608 @UsesJava8 1609 private class OptionalDependencyFactory { 1610 1611 public Object createOptionalDependency(DependencyDescriptor descriptor, String beanName, final Object... args) { 1612 DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) { 1613 @Override 1614 public boolean isRequired() { 1615 return false; 1616 } 1617 @Override 1618 public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) { 1619 return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, requiredType, args) : 1620 super.resolveCandidate(beanName, requiredType, beanFactory)); 1621 } 1622 }; 1623 Object result = doResolveDependency(descriptorToUse, beanName, null, null); 1624 return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result)); 1625 } 1626 } 1627 1628 1629 /** 1630 * Serializable ObjectFactory/ObjectProvider for lazy resolution of a dependency. 1631 */ 1632 private class DependencyObjectProvider implements ObjectProvider<Object>, Serializable { 1633 1634 private final DependencyDescriptor descriptor; 1635 1636 private final boolean optional; 1637 1638 private final String beanName; 1639 1640 public DependencyObjectProvider(DependencyDescriptor descriptor, String beanName) { 1641 this.descriptor = new NestedDependencyDescriptor(descriptor); 1642 this.optional = (this.descriptor.getDependencyType() == javaUtilOptionalClass); 1643 this.beanName = beanName; 1644 } 1645 1646 @Override 1647 public Object getObject() throws BeansException { 1648 if (this.optional) { 1649 return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName); 1650 } 1651 else { 1652 return doResolveDependency(this.descriptor, this.beanName, null, null); 1653 } 1654 } 1655 1656 @Override 1657 public Object getObject(final Object... args) throws BeansException { 1658 if (this.optional) { 1659 return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName, args); 1660 } 1661 else { 1662 DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) { 1663 @Override 1664 public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) { 1665 return ((AbstractBeanFactory) beanFactory).getBean(beanName, requiredType, args); 1666 } 1667 }; 1668 return doResolveDependency(descriptorToUse, this.beanName, null, null); 1669 } 1670 } 1671 1672 @Override 1673 public Object getIfAvailable() throws BeansException { 1674 if (this.optional) { 1675 return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName); 1676 } 1677 else { 1678 DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) { 1679 @Override 1680 public boolean isRequired() { 1681 return false; 1682 } 1683 }; 1684 return doResolveDependency(descriptorToUse, this.beanName, null, null); 1685 } 1686 } 1687 1688 @Override 1689 public Object getIfUnique() throws BeansException { 1690 DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) { 1691 @Override 1692 public boolean isRequired() { 1693 return false; 1694 } 1695 @Override 1696 public Object resolveNotUnique(Class<?> type, Map<String, Object> matchingBeans) { 1697 return null; 1698 } 1699 }; 1700 if (this.optional) { 1701 return new OptionalDependencyFactory().createOptionalDependency(descriptorToUse, this.beanName); 1702 } 1703 else { 1704 return doResolveDependency(descriptorToUse, this.beanName, null, null); 1705 } 1706 } 1707 } 1708 1709 1710 /** 1711 * A {@code javax.inject.Provider} implementation for lazy resolution of a dependency. 1712 */ 1713 private class Jsr330DependencyProvider extends DependencyObjectProvider implements Provider<Object> { 1714 1715 public Jsr330DependencyProvider(DependencyDescriptor descriptor, String beanName) { 1716 super(descriptor, beanName); 1717 } 1718 1719 @Override 1720 public Object get() throws BeansException { 1721 return getObject(); 1722 } 1723 } 1724 1725 1726 /** 1727 * Separate inner class for avoiding a hard dependency on the {@code javax.inject} API. 1728 */ 1729 private class Jsr330ProviderFactory { 1730 1731 public Object createDependencyProvider(DependencyDescriptor descriptor, String beanName) { 1732 return new Jsr330DependencyProvider(descriptor, beanName); 1733 } 1734 } 1735 1736 1737 /** 1738 * An {@link org.springframework.core.OrderComparator.OrderSourceProvider} implementation 1739 * that is aware of the bean metadata of the instances to sort. 1740 * <p>Lookup for the method factory of an instance to sort, if any, and let the 1741 * comparator retrieve the {@link org.springframework.core.annotation.Order} 1742 * value defined on it. This essentially allows for the following construct: 1743 */ 1744 private class FactoryAwareOrderSourceProvider implements OrderComparator.OrderSourceProvider { 1745 1746 private final Map<Object, String> instancesToBeanNames; 1747 1748 public FactoryAwareOrderSourceProvider(Map<Object, String> instancesToBeanNames) { 1749 this.instancesToBeanNames = instancesToBeanNames; 1750 } 1751 1752 @Override 1753 public Object getOrderSource(Object obj) { 1754 String beanName = this.instancesToBeanNames.get(obj); 1755 if (beanName == null || !containsBeanDefinition(beanName)) { 1756 return null; 1757 } 1758 RootBeanDefinition beanDefinition = getMergedLocalBeanDefinition(beanName); 1759 List<Object> sources = new ArrayList<Object>(2); 1760 Method factoryMethod = beanDefinition.getResolvedFactoryMethod(); 1761 if (factoryMethod != null) { 1762 sources.add(factoryMethod); 1763 } 1764 Class<?> targetType = beanDefinition.getTargetType(); 1765 if (targetType != null && targetType != obj.getClass()) { 1766 sources.add(targetType); 1767 } 1768 return sources.toArray(); 1769 } 1770 } 1771 1772}