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}