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