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