001/*
002 * Copyright 2002-2020 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.beans.factory.support;
018
019import java.beans.PropertyDescriptor;
020import java.lang.reflect.Constructor;
021import java.lang.reflect.InvocationTargetException;
022import java.lang.reflect.Method;
023import java.lang.reflect.Modifier;
024import java.security.AccessController;
025import java.security.PrivilegedAction;
026import java.security.PrivilegedActionException;
027import java.security.PrivilegedExceptionAction;
028import java.util.ArrayList;
029import java.util.Arrays;
030import java.util.Collection;
031import java.util.HashSet;
032import java.util.Iterator;
033import java.util.LinkedHashSet;
034import java.util.List;
035import java.util.Set;
036import java.util.TreeSet;
037import java.util.concurrent.ConcurrentHashMap;
038import java.util.concurrent.ConcurrentMap;
039
040import org.springframework.beans.BeanUtils;
041import org.springframework.beans.BeanWrapper;
042import org.springframework.beans.BeanWrapperImpl;
043import org.springframework.beans.BeansException;
044import org.springframework.beans.MutablePropertyValues;
045import org.springframework.beans.PropertyAccessorUtils;
046import org.springframework.beans.PropertyValue;
047import org.springframework.beans.PropertyValues;
048import org.springframework.beans.TypeConverter;
049import org.springframework.beans.factory.Aware;
050import org.springframework.beans.factory.BeanClassLoaderAware;
051import org.springframework.beans.factory.BeanCreationException;
052import org.springframework.beans.factory.BeanCurrentlyInCreationException;
053import org.springframework.beans.factory.BeanDefinitionStoreException;
054import org.springframework.beans.factory.BeanFactory;
055import org.springframework.beans.factory.BeanFactoryAware;
056import org.springframework.beans.factory.BeanNameAware;
057import org.springframework.beans.factory.FactoryBean;
058import org.springframework.beans.factory.InitializingBean;
059import org.springframework.beans.factory.ObjectFactory;
060import org.springframework.beans.factory.UnsatisfiedDependencyException;
061import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
062import org.springframework.beans.factory.config.BeanDefinition;
063import org.springframework.beans.factory.config.BeanPostProcessor;
064import org.springframework.beans.factory.config.ConfigurableBeanFactory;
065import org.springframework.beans.factory.config.ConstructorArgumentValues;
066import org.springframework.beans.factory.config.DependencyDescriptor;
067import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
068import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
069import org.springframework.beans.factory.config.TypedStringValue;
070import org.springframework.core.DefaultParameterNameDiscoverer;
071import org.springframework.core.GenericTypeResolver;
072import org.springframework.core.MethodParameter;
073import org.springframework.core.ParameterNameDiscoverer;
074import org.springframework.core.PriorityOrdered;
075import org.springframework.core.ResolvableType;
076import org.springframework.util.ClassUtils;
077import org.springframework.util.ObjectUtils;
078import org.springframework.util.ReflectionUtils;
079import org.springframework.util.StringUtils;
080
081/**
082 * Abstract bean factory superclass that implements default bean creation,
083 * with the full capabilities specified by the {@link RootBeanDefinition} class.
084 * Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
085 * interface in addition to AbstractBeanFactory's {@link #createBean} method.
086 *
087 * <p>Provides bean creation (with constructor resolution), property population,
088 * wiring (including autowiring), and initialization. Handles runtime bean
089 * references, resolves managed collections, calls initialization methods, etc.
090 * Supports autowiring constructors, properties by name, and properties by type.
091 *
092 * <p>The main template method to be implemented by subclasses is
093 * {@link #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)},
094 * used for autowiring by type. In case of a factory which is capable of searching
095 * its bean definitions, matching beans will typically be implemented through such
096 * a search. For other factory styles, simplified matching algorithms can be implemented.
097 *
098 * <p>Note that this class does <i>not</i> assume or implement bean definition
099 * registry capabilities. See {@link DefaultListableBeanFactory} for an implementation
100 * of the {@link org.springframework.beans.factory.ListableBeanFactory} and
101 * {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI
102 * view of such a factory, respectively.
103 *
104 * @author Rod Johnson
105 * @author Juergen Hoeller
106 * @author Rob Harrop
107 * @author Mark Fisher
108 * @author Costin Leau
109 * @author Chris Beams
110 * @author Sam Brannen
111 * @since 13.02.2004
112 * @see RootBeanDefinition
113 * @see DefaultListableBeanFactory
114 * @see BeanDefinitionRegistry
115 */
116public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
117                implements AutowireCapableBeanFactory {
118
119        /** Strategy for creating bean instances */
120        private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
121
122        /** Resolver strategy for method parameter names */
123        private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
124
125        /** Whether to automatically try to resolve circular references between beans */
126        private boolean allowCircularReferences = true;
127
128        /**
129         * Whether to resort to injecting a raw bean instance in case of circular reference,
130         * even if the injected bean eventually got wrapped.
131         */
132        private boolean allowRawInjectionDespiteWrapping = false;
133
134        /**
135         * Dependency types to ignore on dependency check and autowire, as Set of
136         * Class objects: for example, String. Default is none.
137         */
138        private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();
139
140        /**
141         * Dependency interfaces to ignore on dependency check and autowire, as Set of
142         * Class objects. By default, only the BeanFactory interface is ignored.
143         */
144        private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();
145
146        /** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
147        private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache =
148                        new ConcurrentHashMap<String, BeanWrapper>(16);
149
150        /** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
151        private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
152                        new ConcurrentHashMap<Class<?>, PropertyDescriptor[]>(256);
153
154
155        /**
156         * Create a new AbstractAutowireCapableBeanFactory.
157         */
158        public AbstractAutowireCapableBeanFactory() {
159                super();
160                ignoreDependencyInterface(BeanNameAware.class);
161                ignoreDependencyInterface(BeanFactoryAware.class);
162                ignoreDependencyInterface(BeanClassLoaderAware.class);
163        }
164
165        /**
166         * Create a new AbstractAutowireCapableBeanFactory with the given parent.
167         * @param parentBeanFactory parent bean factory, or {@code null} if none
168         */
169        public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
170                this();
171                setParentBeanFactory(parentBeanFactory);
172        }
173
174
175        /**
176         * Set the instantiation strategy to use for creating bean instances.
177         * Default is CglibSubclassingInstantiationStrategy.
178         * @see CglibSubclassingInstantiationStrategy
179         */
180        public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
181                this.instantiationStrategy = instantiationStrategy;
182        }
183
184        /**
185         * Return the instantiation strategy to use for creating bean instances.
186         */
187        protected InstantiationStrategy getInstantiationStrategy() {
188                return this.instantiationStrategy;
189        }
190
191        /**
192         * Set the ParameterNameDiscoverer to use for resolving method parameter
193         * names if needed (e.g. for constructor names).
194         * <p>Default is a {@link DefaultParameterNameDiscoverer}.
195         */
196        public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
197                this.parameterNameDiscoverer = parameterNameDiscoverer;
198        }
199
200        /**
201         * Return the ParameterNameDiscoverer to use for resolving method parameter
202         * names if needed.
203         */
204        protected ParameterNameDiscoverer getParameterNameDiscoverer() {
205                return this.parameterNameDiscoverer;
206        }
207
208        /**
209         * Set whether to allow circular references between beans - and automatically
210         * try to resolve them.
211         * <p>Note that circular reference resolution means that one of the involved beans
212         * will receive a reference to another bean that is not fully initialized yet.
213         * This can lead to subtle and not-so-subtle side effects on initialization;
214         * it does work fine for many scenarios, though.
215         * <p>Default is "true". Turn this off to throw an exception when encountering
216         * a circular reference, disallowing them completely.
217         * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
218         * between your beans. Refactor your application logic to have the two beans
219         * involved delegate to a third bean that encapsulates their common logic.
220         */
221        public void setAllowCircularReferences(boolean allowCircularReferences) {
222                this.allowCircularReferences = allowCircularReferences;
223        }
224
225        /**
226         * Set whether to allow the raw injection of a bean instance into some other
227         * bean's property, despite the injected bean eventually getting wrapped
228         * (for example, through AOP auto-proxying).
229         * <p>This will only be used as a last resort in case of a circular reference
230         * that cannot be resolved otherwise: essentially, preferring a raw instance
231         * getting injected over a failure of the entire bean wiring process.
232         * <p>Default is "false", as of Spring 2.0. Turn this on to allow for non-wrapped
233         * raw beans injected into some of your references, which was Spring 1.2's
234         * (arguably unclean) default behavior.
235         * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
236         * between your beans, in particular with auto-proxying involved.
237         * @see #setAllowCircularReferences
238         */
239        public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) {
240                this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
241        }
242
243        /**
244         * Ignore the given dependency type for autowiring:
245         * for example, String. Default is none.
246         */
247        public void ignoreDependencyType(Class<?> type) {
248                this.ignoredDependencyTypes.add(type);
249        }
250
251        /**
252         * Ignore the given dependency interface for autowiring.
253         * <p>This will typically be used by application contexts to register
254         * dependencies that are resolved in other ways, like BeanFactory through
255         * BeanFactoryAware or ApplicationContext through ApplicationContextAware.
256         * <p>By default, only the BeanFactoryAware interface is ignored.
257         * For further types to ignore, invoke this method for each type.
258         * @see org.springframework.beans.factory.BeanFactoryAware
259         * @see org.springframework.context.ApplicationContextAware
260         */
261        public void ignoreDependencyInterface(Class<?> ifc) {
262                this.ignoredDependencyInterfaces.add(ifc);
263        }
264
265        @Override
266        public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
267                super.copyConfigurationFrom(otherFactory);
268                if (otherFactory instanceof AbstractAutowireCapableBeanFactory) {
269                        AbstractAutowireCapableBeanFactory otherAutowireFactory =
270                                        (AbstractAutowireCapableBeanFactory) otherFactory;
271                        this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
272                        this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
273                        this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
274                        this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
275                }
276        }
277
278
279        //-------------------------------------------------------------------------
280        // Typical methods for creating and populating external bean instances
281        //-------------------------------------------------------------------------
282
283        @Override
284        @SuppressWarnings("unchecked")
285        public <T> T createBean(Class<T> beanClass) throws BeansException {
286                // Use prototype bean definition, to avoid registering bean as dependent bean.
287                RootBeanDefinition bd = new RootBeanDefinition(beanClass);
288                bd.setScope(SCOPE_PROTOTYPE);
289                bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
290                return (T) createBean(beanClass.getName(), bd, null);
291        }
292
293        @Override
294        public void autowireBean(Object existingBean) {
295                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
296                RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
297                bd.setScope(SCOPE_PROTOTYPE);
298                bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
299                BeanWrapper bw = new BeanWrapperImpl(existingBean);
300                initBeanWrapper(bw);
301                populateBean(bd.getBeanClass().getName(), bd, bw);
302        }
303
304        @Override
305        public Object configureBean(Object existingBean, String beanName) throws BeansException {
306                markBeanAsCreated(beanName);
307                BeanDefinition mbd = getMergedBeanDefinition(beanName);
308                RootBeanDefinition bd = null;
309                if (mbd instanceof RootBeanDefinition) {
310                        RootBeanDefinition rbd = (RootBeanDefinition) mbd;
311                        bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());
312                }
313                if (!mbd.isPrototype()) {
314                        if (bd == null) {
315                                bd = new RootBeanDefinition(mbd);
316                        }
317                        bd.setScope(SCOPE_PROTOTYPE);
318                        bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
319                }
320                BeanWrapper bw = new BeanWrapperImpl(existingBean);
321                initBeanWrapper(bw);
322                populateBean(beanName, bd, bw);
323                return initializeBean(beanName, existingBean, bd);
324        }
325
326        @Override
327        public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException {
328                return resolveDependency(descriptor, requestingBeanName, null, null);
329        }
330
331
332        //-------------------------------------------------------------------------
333        // Specialized methods for fine-grained control over the bean lifecycle
334        //-------------------------------------------------------------------------
335
336        @Override
337        public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
338                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
339                RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
340                bd.setScope(SCOPE_PROTOTYPE);
341                return createBean(beanClass.getName(), bd, null);
342        }
343
344        @Override
345        public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
346                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
347                final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
348                bd.setScope(SCOPE_PROTOTYPE);
349                if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
350                        return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
351                }
352                else {
353                        Object bean;
354                        final BeanFactory parent = this;
355                        if (System.getSecurityManager() != null) {
356                                bean = AccessController.doPrivileged(new PrivilegedAction<Object>() {
357                                        @Override
358                                        public Object run() {
359                                                return getInstantiationStrategy().instantiate(bd, null, parent);
360                                        }
361                                }, getAccessControlContext());
362                        }
363                        else {
364                                bean = getInstantiationStrategy().instantiate(bd, null, parent);
365                        }
366                        populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
367                        return bean;
368                }
369        }
370
371        @Override
372        public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
373                        throws BeansException {
374
375                if (autowireMode == AUTOWIRE_CONSTRUCTOR) {
376                        throw new IllegalArgumentException("AUTOWIRE_CONSTRUCTOR not supported for existing bean instance");
377                }
378                // Use non-singleton bean definition, to avoid registering bean as dependent bean.
379                RootBeanDefinition bd =
380                                new RootBeanDefinition(ClassUtils.getUserClass(existingBean), autowireMode, dependencyCheck);
381                bd.setScope(SCOPE_PROTOTYPE);
382                BeanWrapper bw = new BeanWrapperImpl(existingBean);
383                initBeanWrapper(bw);
384                populateBean(bd.getBeanClass().getName(), bd, bw);
385        }
386
387        @Override
388        public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
389                markBeanAsCreated(beanName);
390                BeanDefinition bd = getMergedBeanDefinition(beanName);
391                BeanWrapper bw = new BeanWrapperImpl(existingBean);
392                initBeanWrapper(bw);
393                applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
394        }
395
396        @Override
397        public Object initializeBean(Object existingBean, String beanName) {
398                return initializeBean(beanName, existingBean, null);
399        }
400
401        @Override
402        public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
403                        throws BeansException {
404
405                Object result = existingBean;
406                for (BeanPostProcessor processor : getBeanPostProcessors()) {
407                        result = processor.postProcessBeforeInitialization(result, beanName);
408                        if (result == null) {
409                                return result;
410                        }
411                }
412                return result;
413        }
414
415        @Override
416        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
417                        throws BeansException {
418
419                Object result = existingBean;
420                for (BeanPostProcessor processor : getBeanPostProcessors()) {
421                        result = processor.postProcessAfterInitialization(result, beanName);
422                        if (result == null) {
423                                return result;
424                        }
425                }
426                return result;
427        }
428
429        @Override
430        public void destroyBean(Object existingBean) {
431                new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
432        }
433
434
435        //---------------------------------------------------------------------
436        // Implementation of relevant AbstractBeanFactory template methods
437        //---------------------------------------------------------------------
438
439        /**
440         * Central method of this class: creates a bean instance,
441         * populates the bean instance, applies post-processors, etc.
442         * @see #doCreateBean
443         */
444        @Override
445        protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
446                if (logger.isDebugEnabled()) {
447                        logger.debug("Creating instance of bean '" + beanName + "'");
448                }
449                RootBeanDefinition mbdToUse = mbd;
450
451                // Make sure bean class is actually resolved at this point, and
452                // clone the bean definition in case of a dynamically resolved Class
453                // which cannot be stored in the shared merged bean definition.
454                Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
455                if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
456                        mbdToUse = new RootBeanDefinition(mbd);
457                        mbdToUse.setBeanClass(resolvedClass);
458                }
459
460                // Prepare method overrides.
461                try {
462                        mbdToUse.prepareMethodOverrides();
463                }
464                catch (BeanDefinitionValidationException ex) {
465                        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
466                                        beanName, "Validation of method overrides failed", ex);
467                }
468
469                try {
470                        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
471                        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
472                        if (bean != null) {
473                                return bean;
474                        }
475                }
476                catch (Throwable ex) {
477                        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
478                                        "BeanPostProcessor before instantiation of bean failed", ex);
479                }
480
481                Object beanInstance = doCreateBean(beanName, mbdToUse, args);
482                if (logger.isDebugEnabled()) {
483                        logger.debug("Finished creating instance of bean '" + beanName + "'");
484                }
485                return beanInstance;
486        }
487
488        /**
489         * Actually create the specified bean. Pre-creation processing has already happened
490         * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
491         * <p>Differentiates between default bean instantiation, use of a
492         * factory method, and autowiring a constructor.
493         * @param beanName the name of the bean
494         * @param mbd the merged bean definition for the bean
495         * @param args explicit arguments to use for constructor or factory method invocation
496         * @return a new instance of the bean
497         * @throws BeanCreationException if the bean could not be created
498         * @see #instantiateBean
499         * @see #instantiateUsingFactoryMethod
500         * @see #autowireConstructor
501         */
502        protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
503                        throws BeanCreationException {
504
505                // Instantiate the bean.
506                BeanWrapper instanceWrapper = null;
507                if (mbd.isSingleton()) {
508                        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
509                }
510                if (instanceWrapper == null) {
511                        instanceWrapper = createBeanInstance(beanName, mbd, args);
512                }
513                final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
514                Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
515                mbd.resolvedTargetType = beanType;
516
517                // Allow post-processors to modify the merged bean definition.
518                synchronized (mbd.postProcessingLock) {
519                        if (!mbd.postProcessed) {
520                                try {
521                                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
522                                }
523                                catch (Throwable ex) {
524                                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
525                                                        "Post-processing of merged bean definition failed", ex);
526                                }
527                                mbd.postProcessed = true;
528                        }
529                }
530
531                // Eagerly cache singletons to be able to resolve circular references
532                // even when triggered by lifecycle interfaces like BeanFactoryAware.
533                boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
534                                isSingletonCurrentlyInCreation(beanName));
535                if (earlySingletonExposure) {
536                        if (logger.isDebugEnabled()) {
537                                logger.debug("Eagerly caching bean '" + beanName +
538                                                "' to allow for resolving potential circular references");
539                        }
540                        addSingletonFactory(beanName, new ObjectFactory<Object>() {
541                                @Override
542                                public Object getObject() throws BeansException {
543                                        return getEarlyBeanReference(beanName, mbd, bean);
544                                }
545                        });
546                }
547
548                // Initialize the bean instance.
549                Object exposedObject = bean;
550                try {
551                        populateBean(beanName, mbd, instanceWrapper);
552                        if (exposedObject != null) {
553                                exposedObject = initializeBean(beanName, exposedObject, mbd);
554                        }
555                }
556                catch (Throwable ex) {
557                        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
558                                throw (BeanCreationException) ex;
559                        }
560                        else {
561                                throw new BeanCreationException(
562                                                mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
563                        }
564                }
565
566                if (earlySingletonExposure) {
567                        Object earlySingletonReference = getSingleton(beanName, false);
568                        if (earlySingletonReference != null) {
569                                if (exposedObject == bean) {
570                                        exposedObject = earlySingletonReference;
571                                }
572                                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
573                                        String[] dependentBeans = getDependentBeans(beanName);
574                                        Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
575                                        for (String dependentBean : dependentBeans) {
576                                                if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
577                                                        actualDependentBeans.add(dependentBean);
578                                                }
579                                        }
580                                        if (!actualDependentBeans.isEmpty()) {
581                                                throw new BeanCurrentlyInCreationException(beanName,
582                                                                "Bean with name '" + beanName + "' has been injected into other beans [" +
583                                                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
584                                                                "] in its raw version as part of a circular reference, but has eventually been " +
585                                                                "wrapped. This means that said other beans do not use the final version of the " +
586                                                                "bean. This is often the result of over-eager type matching - consider using " +
587                                                                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
588                                        }
589                                }
590                        }
591                }
592
593                // Register bean as disposable.
594                try {
595                        registerDisposableBeanIfNecessary(beanName, bean, mbd);
596                }
597                catch (BeanDefinitionValidationException ex) {
598                        throw new BeanCreationException(
599                                        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
600                }
601
602                return exposedObject;
603        }
604
605        @Override
606        protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
607                Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
608                // Apply SmartInstantiationAwareBeanPostProcessors to predict the
609                // eventual type after a before-instantiation shortcut.
610                if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
611                        for (BeanPostProcessor bp : getBeanPostProcessors()) {
612                                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
613                                        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
614                                        Class<?> predicted = ibp.predictBeanType(targetType, beanName);
615                                        if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
616                                                        FactoryBean.class.isAssignableFrom(predicted))) {
617                                                return predicted;
618                                        }
619                                }
620                        }
621                }
622                return targetType;
623        }
624
625        /**
626         * Determine the target type for the given bean definition.
627         * @param beanName the name of the bean (for error handling purposes)
628         * @param mbd the merged bean definition for the bean
629         * @param typesToMatch the types to match in case of internal type matching purposes
630         * (also signals that the returned {@code Class} will never be exposed to application code)
631         * @return the type for the bean if determinable, or {@code null} otherwise
632         */
633        protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
634                Class<?> targetType = mbd.getTargetType();
635                if (targetType == null) {
636                        targetType = (mbd.getFactoryMethodName() != null ?
637                                        getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
638                                        resolveBeanClass(mbd, beanName, typesToMatch));
639                        if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
640                                mbd.resolvedTargetType = targetType;
641                        }
642                }
643                return targetType;
644        }
645
646        /**
647         * Determine the target type for the given bean definition which is based on
648         * a factory method. Only called if there is no singleton instance registered
649         * for the target bean already.
650         * <p>This implementation determines the type matching {@link #createBean}'s
651         * different creation strategies. As far as possible, we'll perform static
652         * type checking to avoid creation of the target bean.
653         * @param beanName the name of the bean (for error handling purposes)
654         * @param mbd the merged bean definition for the bean
655         * @param typesToMatch the types to match in case of internal type matching purposes
656         * (also signals that the returned {@code Class} will never be exposed to application code)
657         * @return the type for the bean if determinable, or {@code null} otherwise
658         * @see #createBean
659         */
660        protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
661                ResolvableType cachedReturnType = mbd.factoryMethodReturnType;
662                if (cachedReturnType != null) {
663                        return cachedReturnType.resolve();
664                }
665
666                Class<?> factoryClass;
667                boolean isStatic = true;
668
669                String factoryBeanName = mbd.getFactoryBeanName();
670                if (factoryBeanName != null) {
671                        if (factoryBeanName.equals(beanName)) {
672                                throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
673                                                "factory-bean reference points back to the same bean definition");
674                        }
675                        // Check declared factory method return type on factory class.
676                        factoryClass = getType(factoryBeanName);
677                        isStatic = false;
678                }
679                else {
680                        // Check declared factory method return type on bean class.
681                        factoryClass = resolveBeanClass(mbd, beanName, typesToMatch);
682                }
683
684                if (factoryClass == null) {
685                        return null;
686                }
687                factoryClass = ClassUtils.getUserClass(factoryClass);
688
689                // If all factory methods have the same return type, return that type.
690                // Can't clearly figure out exact method due to type converting / autowiring!
691                Class<?> commonType = null;
692                Method uniqueCandidate = null;
693                int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount();
694                Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass);
695                for (Method candidate : candidates) {
696                        if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) &&
697                                        candidate.getParameterTypes().length >= minNrOfArgs) {
698                                // Declared type variables to inspect?
699                                if (candidate.getTypeParameters().length > 0) {
700                                        try {
701                                                // Fully resolve parameter names and argument values.
702                                                Class<?>[] paramTypes = candidate.getParameterTypes();
703                                                String[] paramNames = null;
704                                                ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
705                                                if (pnd != null) {
706                                                        paramNames = pnd.getParameterNames(candidate);
707                                                }
708                                                ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
709                                                Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
710                                                                new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length);
711                                                Object[] args = new Object[paramTypes.length];
712                                                for (int i = 0; i < args.length; i++) {
713                                                        ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(
714                                                                        i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders);
715                                                        if (valueHolder == null) {
716                                                                valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders);
717                                                        }
718                                                        if (valueHolder != null) {
719                                                                args[i] = valueHolder.getValue();
720                                                                usedValueHolders.add(valueHolder);
721                                                        }
722                                                }
723                                                Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(
724                                                                candidate, args, getBeanClassLoader());
725                                                if (returnType != null) {
726                                                        uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ?
727                                                                        candidate : null);
728                                                        commonType = ClassUtils.determineCommonAncestor(returnType, commonType);
729                                                        if (commonType == null) {
730                                                                // Ambiguous return types found: return null to indicate "not determinable".
731                                                                return null;
732                                                        }
733                                                }
734                                        }
735                                        catch (Throwable ex) {
736                                                if (logger.isDebugEnabled()) {
737                                                        logger.debug("Failed to resolve generic return type for factory method: " + ex);
738                                                }
739                                        }
740                                }
741                                else {
742                                        uniqueCandidate = (commonType == null ? candidate : null);
743                                        commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType);
744                                        if (commonType == null) {
745                                                // Ambiguous return types found: return null to indicate "not determinable".
746                                                return null;
747                                        }
748                                }
749                        }
750                }
751
752                if (commonType == null) {
753                        return null;
754                }
755                // Common return type found: all factory methods return same type. For a non-parameterized
756                // unique candidate, cache the full type declaration context of the target factory method.
757                cachedReturnType = (uniqueCandidate != null ?
758                                ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType));
759                mbd.factoryMethodReturnType = cachedReturnType;
760                return cachedReturnType.resolve();
761        }
762
763        /**
764         * This implementation attempts to query the FactoryBean's generic parameter metadata
765         * if present to determine the object type. If not present, i.e. the FactoryBean is
766         * declared as a raw type, checks the FactoryBean's {@code getObjectType} method
767         * on a plain instance of the FactoryBean, without bean properties applied yet.
768         * If this doesn't return a type yet, a full creation of the FactoryBean is
769         * used as fallback (through delegation to the superclass's implementation).
770         * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
771         * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
772         * it will be fully created to check the type of its exposed object.
773         */
774        @Override
775        protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
776                String factoryBeanName = mbd.getFactoryBeanName();
777                String factoryMethodName = mbd.getFactoryMethodName();
778
779                if (factoryBeanName != null) {
780                        if (factoryMethodName != null) {
781                                // Try to obtain the FactoryBean's object type from its factory method declaration
782                                // without instantiating the containing bean at all.
783                                BeanDefinition fbDef = getBeanDefinition(factoryBeanName);
784                                if (fbDef instanceof AbstractBeanDefinition) {
785                                        AbstractBeanDefinition afbDef = (AbstractBeanDefinition) fbDef;
786                                        if (afbDef.hasBeanClass()) {
787                                                Class<?> result = getTypeForFactoryBeanFromMethod(afbDef.getBeanClass(), factoryMethodName);
788                                                if (result != null) {
789                                                        return result;
790                                                }
791                                        }
792                                }
793                        }
794                        // If not resolvable above and the referenced factory bean doesn't exist yet,
795                        // exit here - we don't want to force the creation of another bean just to
796                        // obtain a FactoryBean's object type...
797                        if (!isBeanEligibleForMetadataCaching(factoryBeanName)) {
798                                return null;
799                        }
800                }
801
802                // Let's obtain a shortcut instance for an early getObjectType() call...
803                FactoryBean<?> fb = (mbd.isSingleton() ?
804                                getSingletonFactoryBeanForTypeCheck(beanName, mbd) :
805                                getNonSingletonFactoryBeanForTypeCheck(beanName, mbd));
806
807                if (fb != null) {
808                        // Try to obtain the FactoryBean's object type from this early stage of the instance.
809                        Class<?> result = getTypeForFactoryBean(fb);
810                        if (result != null) {
811                                return result;
812                        }
813                        else {
814                                // No type found for shortcut FactoryBean instance:
815                                // fall back to full creation of the FactoryBean instance.
816                                return super.getTypeForFactoryBean(beanName, mbd);
817                        }
818                }
819
820                if (factoryBeanName == null && mbd.hasBeanClass()) {
821                        // No early bean instantiation possible: determine FactoryBean's type from
822                        // static factory method signature or from class inheritance hierarchy...
823                        if (factoryMethodName != null) {
824                                return getTypeForFactoryBeanFromMethod(mbd.getBeanClass(), factoryMethodName);
825                        }
826                        else {
827                                return GenericTypeResolver.resolveTypeArgument(mbd.getBeanClass(), FactoryBean.class);
828                        }
829                }
830
831                return null;
832        }
833
834        /**
835         * Introspect the factory method signatures on the given bean class,
836         * trying to find a common {@code FactoryBean} object type declared there.
837         * @param beanClass the bean class to find the factory method on
838         * @param factoryMethodName the name of the factory method
839         * @return the common {@code FactoryBean} object type, or {@code null} if none
840         */
841        private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, final String factoryMethodName) {
842                class Holder { Class<?> value = null; }
843                final Holder objectType = new Holder();
844
845                // CGLIB subclass methods hide generic parameters; look at the original user class.
846                Class<?> fbClass = ClassUtils.getUserClass(beanClass);
847
848                // Find the given factory method, taking into account that in the case of
849                // @Bean methods, there may be parameters present.
850                ReflectionUtils.doWithMethods(fbClass,
851                                new ReflectionUtils.MethodCallback() {
852                                        @Override
853                                        public void doWith(Method method) {
854                                                if (method.getName().equals(factoryMethodName) &&
855                                                                FactoryBean.class.isAssignableFrom(method.getReturnType())) {
856                                                        Class<?> currentType = GenericTypeResolver.resolveReturnTypeArgument(
857                                                                        method, FactoryBean.class);
858                                                        if (currentType != null) {
859                                                                objectType.value = ClassUtils.determineCommonAncestor(currentType, objectType.value);
860                                                        }
861                                                }
862                                        }
863                                });
864
865                return (objectType.value != null && Object.class != objectType.value ? objectType.value : null);
866        }
867
868        /**
869         * Obtain a reference for early access to the specified bean,
870         * typically for the purpose of resolving a circular reference.
871         * @param beanName the name of the bean (for error handling purposes)
872         * @param mbd the merged bean definition for the bean
873         * @param bean the raw bean instance
874         * @return the object to expose as bean reference
875         */
876        protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
877                Object exposedObject = bean;
878                if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
879                        for (BeanPostProcessor bp : getBeanPostProcessors()) {
880                                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
881                                        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
882                                        exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
883                                        if (exposedObject == null) {
884                                                return null;
885                                        }
886                                }
887                        }
888                }
889                return exposedObject;
890        }
891
892
893        //---------------------------------------------------------------------
894        // Implementation methods
895        //---------------------------------------------------------------------
896
897        /**
898         * Obtain a "shortcut" singleton FactoryBean instance to use for a
899         * {@code getObjectType()} call, without full initialization of the FactoryBean.
900         * @param beanName the name of the bean
901         * @param mbd the bean definition for the bean
902         * @return the FactoryBean instance, or {@code null} to indicate
903         * that we couldn't obtain a shortcut FactoryBean instance
904         */
905        private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
906                synchronized (getSingletonMutex()) {
907                        BeanWrapper bw = this.factoryBeanInstanceCache.get(beanName);
908                        if (bw != null) {
909                                return (FactoryBean<?>) bw.getWrappedInstance();
910                        }
911                        Object beanInstance = getSingleton(beanName, false);
912                        if (beanInstance instanceof FactoryBean) {
913                                return (FactoryBean<?>) beanInstance;
914                        }
915                        if (isSingletonCurrentlyInCreation(beanName) ||
916                                        (mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
917                                return null;
918                        }
919
920                        Object instance;
921                        try {
922                                // Mark this bean as currently in creation, even if just partially.
923                                beforeSingletonCreation(beanName);
924                                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
925                                instance = resolveBeforeInstantiation(beanName, mbd);
926                                if (instance == null) {
927                                        bw = createBeanInstance(beanName, mbd, null);
928                                        instance = bw.getWrappedInstance();
929                                }
930                        }
931                        finally {
932                                // Finished partial creation of this bean.
933                                afterSingletonCreation(beanName);
934                        }
935
936                        FactoryBean<?> fb = getFactoryBean(beanName, instance);
937                        if (bw != null) {
938                                this.factoryBeanInstanceCache.put(beanName, bw);
939                        }
940                        return fb;
941                }
942        }
943
944        /**
945         * Obtain a "shortcut" non-singleton FactoryBean instance to use for a
946         * {@code getObjectType()} call, without full initialization of the FactoryBean.
947         * @param beanName the name of the bean
948         * @param mbd the bean definition for the bean
949         * @return the FactoryBean instance, or {@code null} to indicate
950         * that we couldn't obtain a shortcut FactoryBean instance
951         */
952        private FactoryBean<?> getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
953                if (isPrototypeCurrentlyInCreation(beanName)) {
954                        return null;
955                }
956
957                Object instance;
958                try {
959                        // Mark this bean as currently in creation, even if just partially.
960                        beforePrototypeCreation(beanName);
961                        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
962                        instance = resolveBeforeInstantiation(beanName, mbd);
963                        if (instance == null) {
964                                BeanWrapper bw = createBeanInstance(beanName, mbd, null);
965                                instance = bw.getWrappedInstance();
966                        }
967                }
968                catch (BeanCreationException ex) {
969                        // Can only happen when getting a FactoryBean.
970                        if (logger.isDebugEnabled()) {
971                                logger.debug("Bean creation exception on non-singleton FactoryBean type check: " + ex);
972                        }
973                        onSuppressedException(ex);
974                        return null;
975                }
976                finally {
977                        // Finished partial creation of this bean.
978                        afterPrototypeCreation(beanName);
979                }
980
981                return getFactoryBean(beanName, instance);
982        }
983
984        /**
985         * Apply MergedBeanDefinitionPostProcessors to the specified bean definition,
986         * invoking their {@code postProcessMergedBeanDefinition} methods.
987         * @param mbd the merged bean definition for the bean
988         * @param beanType the actual type of the managed bean instance
989         * @param beanName the name of the bean
990         * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
991         */
992        protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
993                for (BeanPostProcessor bp : getBeanPostProcessors()) {
994                        if (bp instanceof MergedBeanDefinitionPostProcessor) {
995                                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
996                                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
997                        }
998                }
999        }
1000
1001        /**
1002         * Apply before-instantiation post-processors, resolving whether there is a
1003         * before-instantiation shortcut for the specified bean.
1004         * @param beanName the name of the bean
1005         * @param mbd the bean definition for the bean
1006         * @return the shortcut-determined bean instance, or {@code null} if none
1007         */
1008        protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
1009                Object bean = null;
1010                if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
1011                        // Make sure bean class is actually resolved at this point.
1012                        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
1013                                Class<?> targetType = determineTargetType(beanName, mbd);
1014                                if (targetType != null) {
1015                                        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
1016                                        if (bean != null) {
1017                                                bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
1018                                        }
1019                                }
1020                        }
1021                        mbd.beforeInstantiationResolved = (bean != null);
1022                }
1023                return bean;
1024        }
1025
1026        /**
1027         * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
1028         * (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
1029         * <p>Any returned object will be used as the bean instead of actually instantiating
1030         * the target bean. A {@code null} return value from the post-processor will
1031         * result in the target bean being instantiated.
1032         * @param beanClass the class of the bean to be instantiated
1033         * @param beanName the name of the bean
1034         * @return the bean object to use instead of a default instance of the target bean, or {@code null}
1035         * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
1036         */
1037        protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
1038                for (BeanPostProcessor bp : getBeanPostProcessors()) {
1039                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
1040                                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
1041                                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
1042                                if (result != null) {
1043                                        return result;
1044                                }
1045                        }
1046                }
1047                return null;
1048        }
1049
1050        /**
1051         * Create a new instance for the specified bean, using an appropriate instantiation strategy:
1052         * factory method, constructor autowiring, or simple instantiation.
1053         * @param beanName the name of the bean
1054         * @param mbd the bean definition for the bean
1055         * @param args explicit arguments to use for constructor or factory method invocation
1056         * @return a BeanWrapper for the new instance
1057         * @see #instantiateUsingFactoryMethod
1058         * @see #autowireConstructor
1059         * @see #instantiateBean
1060         */
1061        protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
1062                // Make sure bean class is actually resolved at this point.
1063                Class<?> beanClass = resolveBeanClass(mbd, beanName);
1064
1065                if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
1066                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
1067                                        "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
1068                }
1069
1070                if (mbd.getFactoryMethodName() != null) {
1071                        return instantiateUsingFactoryMethod(beanName, mbd, args);
1072                }
1073
1074                // Shortcut when re-creating the same bean...
1075                boolean resolved = false;
1076                boolean autowireNecessary = false;
1077                if (args == null) {
1078                        synchronized (mbd.constructorArgumentLock) {
1079                                if (mbd.resolvedConstructorOrFactoryMethod != null) {
1080                                        resolved = true;
1081                                        autowireNecessary = mbd.constructorArgumentsResolved;
1082                                }
1083                        }
1084                }
1085                if (resolved) {
1086                        if (autowireNecessary) {
1087                                return autowireConstructor(beanName, mbd, null, null);
1088                        }
1089                        else {
1090                                return instantiateBean(beanName, mbd);
1091                        }
1092                }
1093
1094                // Candidate constructors for autowiring?
1095                Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
1096                if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
1097                                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
1098                        return autowireConstructor(beanName, mbd, ctors, args);
1099                }
1100
1101                // No special handling: simply use no-arg constructor.
1102                return instantiateBean(beanName, mbd);
1103        }
1104
1105        /**
1106         * Determine candidate constructors to use for the given bean, checking all registered
1107         * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
1108         * @param beanClass the raw class of the bean
1109         * @param beanName the name of the bean
1110         * @return the candidate constructors, or {@code null} if none specified
1111         * @throws org.springframework.beans.BeansException in case of errors
1112         * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
1113         */
1114        protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName)
1115                        throws BeansException {
1116
1117                if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
1118                        for (BeanPostProcessor bp : getBeanPostProcessors()) {
1119                                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
1120                                        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
1121                                        Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
1122                                        if (ctors != null) {
1123                                                return ctors;
1124                                        }
1125                                }
1126                        }
1127                }
1128                return null;
1129        }
1130
1131        /**
1132         * Instantiate the given bean using its default constructor.
1133         * @param beanName the name of the bean
1134         * @param mbd the bean definition for the bean
1135         * @return a BeanWrapper for the new instance
1136         */
1137        protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
1138                try {
1139                        Object beanInstance;
1140                        final BeanFactory parent = this;
1141                        if (System.getSecurityManager() != null) {
1142                                beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
1143                                        @Override
1144                                        public Object run() {
1145                                                return getInstantiationStrategy().instantiate(mbd, beanName, parent);
1146                                        }
1147                                }, getAccessControlContext());
1148                        }
1149                        else {
1150                                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
1151                        }
1152                        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
1153                        initBeanWrapper(bw);
1154                        return bw;
1155                }
1156                catch (Throwable ex) {
1157                        throw new BeanCreationException(
1158                                        mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
1159                }
1160        }
1161
1162        /**
1163         * Instantiate the bean using a named factory method. The method may be static, if the
1164         * mbd parameter specifies a class, rather than a factoryBean, or an instance variable
1165         * on a factory object itself configured using Dependency Injection.
1166         * @param beanName the name of the bean
1167         * @param mbd the bean definition for the bean
1168         * @param explicitArgs argument values passed in programmatically via the getBean method,
1169         * or {@code null} if none (-> use constructor argument values from bean definition)
1170         * @return a BeanWrapper for the new instance
1171         * @see #getBean(String, Object[])
1172         */
1173        protected BeanWrapper instantiateUsingFactoryMethod(
1174                        String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
1175
1176                return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
1177        }
1178
1179        /**
1180         * "autowire constructor" (with constructor arguments by type) behavior.
1181         * Also applied if explicit constructor argument values are specified,
1182         * matching all remaining arguments with beans from the bean factory.
1183         * <p>This corresponds to constructor injection: In this mode, a Spring
1184         * bean factory is able to host components that expect constructor-based
1185         * dependency resolution.
1186         * @param beanName the name of the bean
1187         * @param mbd the bean definition for the bean
1188         * @param ctors the chosen candidate constructors
1189         * @param explicitArgs argument values passed in programmatically via the getBean method,
1190         * or {@code null} if none (-> use constructor argument values from bean definition)
1191         * @return a BeanWrapper for the new instance
1192         */
1193        protected BeanWrapper autowireConstructor(
1194                        String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
1195
1196                return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
1197        }
1198
1199        /**
1200         * Populate the bean instance in the given BeanWrapper with the property values
1201         * from the bean definition.
1202         * @param beanName the name of the bean
1203         * @param mbd the bean definition for the bean
1204         * @param bw the BeanWrapper with bean instance
1205         */
1206        protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
1207                PropertyValues pvs = mbd.getPropertyValues();
1208
1209                if (bw == null) {
1210                        if (!pvs.isEmpty()) {
1211                                throw new BeanCreationException(
1212                                                mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
1213                        }
1214                        else {
1215                                // Skip property population phase for null instance.
1216                                return;
1217                        }
1218                }
1219
1220                // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
1221                // state of the bean before properties are set. This can be used, for example,
1222                // to support styles of field injection.
1223                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
1224                        for (BeanPostProcessor bp : getBeanPostProcessors()) {
1225                                if (bp instanceof InstantiationAwareBeanPostProcessor) {
1226                                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
1227                                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
1228                                                return;
1229                                        }
1230                                }
1231                        }
1232                }
1233
1234                int resolvedAutowireMode = mbd.getResolvedAutowireMode();
1235                if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
1236                        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
1237                        // Add property values based on autowire by name if applicable.
1238                        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
1239                                autowireByName(beanName, mbd, bw, newPvs);
1240                        }
1241                        // Add property values based on autowire by type if applicable.
1242                        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
1243                                autowireByType(beanName, mbd, bw, newPvs);
1244                        }
1245                        pvs = newPvs;
1246                }
1247
1248                boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
1249                boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
1250
1251                if (hasInstAwareBpps || needsDepCheck) {
1252                        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
1253                        if (hasInstAwareBpps) {
1254                                for (BeanPostProcessor bp : getBeanPostProcessors()) {
1255                                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
1256                                                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
1257                                                pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
1258                                                if (pvs == null) {
1259                                                        return;
1260                                                }
1261                                        }
1262                                }
1263                        }
1264                        if (needsDepCheck) {
1265                                checkDependencies(beanName, mbd, filteredPds, pvs);
1266                        }
1267                }
1268
1269                applyPropertyValues(beanName, mbd, bw, pvs);
1270        }
1271
1272        /**
1273         * Fill in any missing property values with references to
1274         * other beans in this factory if autowire is set to "byName".
1275         * @param beanName the name of the bean we're wiring up.
1276         * Useful for debugging messages; not used functionally.
1277         * @param mbd bean definition to update through autowiring
1278         * @param bw the BeanWrapper from which we can obtain information about the bean
1279         * @param pvs the PropertyValues to register wired objects with
1280         */
1281        protected void autowireByName(
1282                        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
1283
1284                String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
1285                for (String propertyName : propertyNames) {
1286                        if (containsBean(propertyName)) {
1287                                Object bean = getBean(propertyName);
1288                                pvs.add(propertyName, bean);
1289                                registerDependentBean(propertyName, beanName);
1290                                if (logger.isDebugEnabled()) {
1291                                        logger.debug("Added autowiring by name from bean name '" + beanName +
1292                                                        "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
1293                                }
1294                        }
1295                        else {
1296                                if (logger.isTraceEnabled()) {
1297                                        logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
1298                                                        "' by name: no matching bean found");
1299                                }
1300                        }
1301                }
1302        }
1303
1304        /**
1305         * Abstract method defining "autowire by type" (bean properties by type) behavior.
1306         * <p>This is like PicoContainer default, in which there must be exactly one bean
1307         * of the property type in the bean factory. This makes bean factories simple to
1308         * configure for small namespaces, but doesn't work as well as standard Spring
1309         * behavior for bigger applications.
1310         * @param beanName the name of the bean to autowire by type
1311         * @param mbd the merged bean definition to update through autowiring
1312         * @param bw the BeanWrapper from which we can obtain information about the bean
1313         * @param pvs the PropertyValues to register wired objects with
1314         */
1315        protected void autowireByType(
1316                        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
1317
1318                TypeConverter converter = getCustomTypeConverter();
1319                if (converter == null) {
1320                        converter = bw;
1321                }
1322
1323                Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
1324                String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
1325                for (String propertyName : propertyNames) {
1326                        try {
1327                                PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
1328                                // Don't try autowiring by type for type Object: never makes sense,
1329                                // even if it technically is a unsatisfied, non-simple property.
1330                                if (Object.class != pd.getPropertyType()) {
1331                                        MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
1332                                        // Do not allow eager init for type matching in case of a prioritized post-processor.
1333                                        boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
1334                                        DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
1335                                        Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
1336                                        if (autowiredArgument != null) {
1337                                                pvs.add(propertyName, autowiredArgument);
1338                                        }
1339                                        for (String autowiredBeanName : autowiredBeanNames) {
1340                                                registerDependentBean(autowiredBeanName, beanName);
1341                                                if (logger.isDebugEnabled()) {
1342                                                        logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
1343                                                                        propertyName + "' to bean named '" + autowiredBeanName + "'");
1344                                                }
1345                                        }
1346                                        autowiredBeanNames.clear();
1347                                }
1348                        }
1349                        catch (BeansException ex) {
1350                                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
1351                        }
1352                }
1353        }
1354
1355
1356        /**
1357         * Return an array of non-simple bean properties that are unsatisfied.
1358         * These are probably unsatisfied references to other beans in the
1359         * factory. Does not include simple properties like primitives or Strings.
1360         * @param mbd the merged bean definition the bean was created with
1361         * @param bw the BeanWrapper the bean was created with
1362         * @return an array of bean property names
1363         * @see org.springframework.beans.BeanUtils#isSimpleProperty
1364         */
1365        protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
1366                Set<String> result = new TreeSet<String>();
1367                PropertyValues pvs = mbd.getPropertyValues();
1368                PropertyDescriptor[] pds = bw.getPropertyDescriptors();
1369                for (PropertyDescriptor pd : pds) {
1370                        if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
1371                                        !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
1372                                result.add(pd.getName());
1373                        }
1374                }
1375                return StringUtils.toStringArray(result);
1376        }
1377
1378        /**
1379         * Extract a filtered set of PropertyDescriptors from the given BeanWrapper,
1380         * excluding ignored dependency types or properties defined on ignored dependency interfaces.
1381         * @param bw the BeanWrapper the bean was created with
1382         * @param cache whether to cache filtered PropertyDescriptors for the given bean Class
1383         * @return the filtered PropertyDescriptors
1384         * @see #isExcludedFromDependencyCheck
1385         * @see #filterPropertyDescriptorsForDependencyCheck(org.springframework.beans.BeanWrapper)
1386         */
1387        protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw, boolean cache) {
1388                PropertyDescriptor[] filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
1389                if (filtered == null) {
1390                        filtered = filterPropertyDescriptorsForDependencyCheck(bw);
1391                        if (cache) {
1392                                PropertyDescriptor[] existing =
1393                                                this.filteredPropertyDescriptorsCache.putIfAbsent(bw.getWrappedClass(), filtered);
1394                                if (existing != null) {
1395                                        filtered = existing;
1396                                }
1397                        }
1398                }
1399                return filtered;
1400        }
1401
1402        /**
1403         * Extract a filtered set of PropertyDescriptors from the given BeanWrapper,
1404         * excluding ignored dependency types or properties defined on ignored dependency interfaces.
1405         * @param bw the BeanWrapper the bean was created with
1406         * @return the filtered PropertyDescriptors
1407         * @see #isExcludedFromDependencyCheck
1408         */
1409        protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) {
1410                List<PropertyDescriptor> pds =
1411                                new ArrayList<PropertyDescriptor>(Arrays.asList(bw.getPropertyDescriptors()));
1412                for (Iterator<PropertyDescriptor> it = pds.iterator(); it.hasNext();) {
1413                        PropertyDescriptor pd = it.next();
1414                        if (isExcludedFromDependencyCheck(pd)) {
1415                                it.remove();
1416                        }
1417                }
1418                return pds.toArray(new PropertyDescriptor[pds.size()]);
1419        }
1420
1421        /**
1422         * Determine whether the given bean property is excluded from dependency checks.
1423         * <p>This implementation excludes properties defined by CGLIB and
1424         * properties whose type matches an ignored dependency type or which
1425         * are defined by an ignored dependency interface.
1426         * @param pd the PropertyDescriptor of the bean property
1427         * @return whether the bean property is excluded
1428         * @see #ignoreDependencyType(Class)
1429         * @see #ignoreDependencyInterface(Class)
1430         */
1431        protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
1432                return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
1433                                this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
1434                                AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
1435        }
1436
1437        /**
1438         * Perform a dependency check that all properties exposed have been set,
1439         * if desired. Dependency checks can be objects (collaborating beans),
1440         * simple (primitives and String), or all (both).
1441         * @param beanName the name of the bean
1442         * @param mbd the merged bean definition the bean was created with
1443         * @param pds the relevant property descriptors for the target bean
1444         * @param pvs the property values to be applied to the bean
1445         * @see #isExcludedFromDependencyCheck(java.beans.PropertyDescriptor)
1446         */
1447        protected void checkDependencies(
1448                        String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs)
1449                        throws UnsatisfiedDependencyException {
1450
1451                int dependencyCheck = mbd.getDependencyCheck();
1452                for (PropertyDescriptor pd : pds) {
1453                        if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) {
1454                                boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
1455                                boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) ||
1456                                                (isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
1457                                                (!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
1458                                if (unsatisfied) {
1459                                        throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
1460                                                        "Set this property value or disable dependency checking for this bean.");
1461                                }
1462                        }
1463                }
1464        }
1465
1466        /**
1467         * Apply the given property values, resolving any runtime references
1468         * to other beans in this bean factory. Must use deep copy, so we
1469         * don't permanently modify this property.
1470         * @param beanName the bean name passed for better exception information
1471         * @param mbd the merged bean definition
1472         * @param bw the BeanWrapper wrapping the target object
1473         * @param pvs the new property values
1474         */
1475        protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
1476                if (pvs == null || pvs.isEmpty()) {
1477                        return;
1478                }
1479
1480                if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
1481                        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
1482                }
1483
1484                MutablePropertyValues mpvs = null;
1485                List<PropertyValue> original;
1486
1487                if (pvs instanceof MutablePropertyValues) {
1488                        mpvs = (MutablePropertyValues) pvs;
1489                        if (mpvs.isConverted()) {
1490                                // Shortcut: use the pre-converted values as-is.
1491                                try {
1492                                        bw.setPropertyValues(mpvs);
1493                                        return;
1494                                }
1495                                catch (BeansException ex) {
1496                                        throw new BeanCreationException(
1497                                                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
1498                                }
1499                        }
1500                        original = mpvs.getPropertyValueList();
1501                }
1502                else {
1503                        original = Arrays.asList(pvs.getPropertyValues());
1504                }
1505
1506                TypeConverter converter = getCustomTypeConverter();
1507                if (converter == null) {
1508                        converter = bw;
1509                }
1510                BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
1511
1512                // Create a deep copy, resolving any references for values.
1513                List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
1514                boolean resolveNecessary = false;
1515                for (PropertyValue pv : original) {
1516                        if (pv.isConverted()) {
1517                                deepCopy.add(pv);
1518                        }
1519                        else {
1520                                String propertyName = pv.getName();
1521                                Object originalValue = pv.getValue();
1522                                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
1523                                Object convertedValue = resolvedValue;
1524                                boolean convertible = bw.isWritableProperty(propertyName) &&
1525                                                !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
1526                                if (convertible) {
1527                                        convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
1528                                }
1529                                // Possibly store converted value in merged bean definition,
1530                                // in order to avoid re-conversion for every created bean instance.
1531                                if (resolvedValue == originalValue) {
1532                                        if (convertible) {
1533                                                pv.setConvertedValue(convertedValue);
1534                                        }
1535                                        deepCopy.add(pv);
1536                                }
1537                                else if (convertible && originalValue instanceof TypedStringValue &&
1538                                                !((TypedStringValue) originalValue).isDynamic() &&
1539                                                !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
1540                                        pv.setConvertedValue(convertedValue);
1541                                        deepCopy.add(pv);
1542                                }
1543                                else {
1544                                        resolveNecessary = true;
1545                                        deepCopy.add(new PropertyValue(pv, convertedValue));
1546                                }
1547                        }
1548                }
1549                if (mpvs != null && !resolveNecessary) {
1550                        mpvs.setConverted();
1551                }
1552
1553                // Set our (possibly massaged) deep copy.
1554                try {
1555                        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
1556                }
1557                catch (BeansException ex) {
1558                        throw new BeanCreationException(
1559                                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
1560                }
1561        }
1562
1563        /**
1564         * Convert the given value for the specified target property.
1565         */
1566        private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
1567                if (converter instanceof BeanWrapperImpl) {
1568                        return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
1569                }
1570                else {
1571                        PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
1572                        MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
1573                        return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam);
1574                }
1575        }
1576
1577
1578        /**
1579         * Initialize the given bean instance, applying factory callbacks
1580         * as well as init methods and bean post processors.
1581         * <p>Called from {@link #createBean} for traditionally defined beans,
1582         * and from {@link #initializeBean} for existing bean instances.
1583         * @param beanName the bean name in the factory (for debugging purposes)
1584         * @param bean the new bean instance we may need to initialize
1585         * @param mbd the bean definition that the bean was created with
1586         * (can also be {@code null}, if given an existing bean instance)
1587         * @return the initialized bean instance (potentially wrapped)
1588         * @see BeanNameAware
1589         * @see BeanClassLoaderAware
1590         * @see BeanFactoryAware
1591         * @see #applyBeanPostProcessorsBeforeInitialization
1592         * @see #invokeInitMethods
1593         * @see #applyBeanPostProcessorsAfterInitialization
1594         */
1595        protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
1596                if (System.getSecurityManager() != null) {
1597                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
1598                                @Override
1599                                public Object run() {
1600                                        invokeAwareMethods(beanName, bean);
1601                                        return null;
1602                                }
1603                        }, getAccessControlContext());
1604                }
1605                else {
1606                        invokeAwareMethods(beanName, bean);
1607                }
1608
1609                Object wrappedBean = bean;
1610                if (mbd == null || !mbd.isSynthetic()) {
1611                        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
1612                }
1613
1614                try {
1615                        invokeInitMethods(beanName, wrappedBean, mbd);
1616                }
1617                catch (Throwable ex) {
1618                        throw new BeanCreationException(
1619                                        (mbd != null ? mbd.getResourceDescription() : null),
1620                                        beanName, "Invocation of init method failed", ex);
1621                }
1622                if (mbd == null || !mbd.isSynthetic()) {
1623                        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
1624                }
1625                return wrappedBean;
1626        }
1627
1628        private void invokeAwareMethods(final String beanName, final Object bean) {
1629                if (bean instanceof Aware) {
1630                        if (bean instanceof BeanNameAware) {
1631                                ((BeanNameAware) bean).setBeanName(beanName);
1632                        }
1633                        if (bean instanceof BeanClassLoaderAware) {
1634                                ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
1635                        }
1636                        if (bean instanceof BeanFactoryAware) {
1637                                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
1638                        }
1639                }
1640        }
1641
1642        /**
1643         * Give a bean a chance to react now all its properties are set,
1644         * and a chance to know about its owning bean factory (this object).
1645         * This means checking whether the bean implements InitializingBean or defines
1646         * a custom init method, and invoking the necessary callback(s) if it does.
1647         * @param beanName the bean name in the factory (for debugging purposes)
1648         * @param bean the new bean instance we may need to initialize
1649         * @param mbd the merged bean definition that the bean was created with
1650         * (can also be {@code null}, if given an existing bean instance)
1651         * @throws Throwable if thrown by init methods or by the invocation process
1652         * @see #invokeCustomInitMethod
1653         */
1654        protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
1655                        throws Throwable {
1656
1657                boolean isInitializingBean = (bean instanceof InitializingBean);
1658                if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
1659                        if (logger.isDebugEnabled()) {
1660                                logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
1661                        }
1662                        if (System.getSecurityManager() != null) {
1663                                try {
1664                                        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
1665                                                @Override
1666                                                public Object run() throws Exception {
1667                                                        ((InitializingBean) bean).afterPropertiesSet();
1668                                                        return null;
1669                                                }
1670                                        }, getAccessControlContext());
1671                                }
1672                                catch (PrivilegedActionException pae) {
1673                                        throw pae.getException();
1674                                }
1675                        }
1676                        else {
1677                                ((InitializingBean) bean).afterPropertiesSet();
1678                        }
1679                }
1680
1681                if (mbd != null) {
1682                        String initMethodName = mbd.getInitMethodName();
1683                        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
1684                                        !mbd.isExternallyManagedInitMethod(initMethodName)) {
1685                                invokeCustomInitMethod(beanName, bean, mbd);
1686                        }
1687                }
1688        }
1689
1690        /**
1691         * Invoke the specified custom init method on the given bean.
1692         * Called by invokeInitMethods.
1693         * <p>Can be overridden in subclasses for custom resolution of init
1694         * methods with arguments.
1695         * @see #invokeInitMethods
1696         */
1697        protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
1698                        throws Throwable {
1699
1700                String initMethodName = mbd.getInitMethodName();
1701                final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
1702                                BeanUtils.findMethod(bean.getClass(), initMethodName) :
1703                                ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
1704                if (initMethod == null) {
1705                        if (mbd.isEnforceInitMethod()) {
1706                                throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
1707                                                initMethodName + "' on bean with name '" + beanName + "'");
1708                        }
1709                        else {
1710                                if (logger.isDebugEnabled()) {
1711                                        logger.debug("No default init method named '" + initMethodName +
1712                                                        "' found on bean with name '" + beanName + "'");
1713                                }
1714                                // Ignore non-existent default lifecycle methods.
1715                                return;
1716                        }
1717                }
1718
1719                if (logger.isDebugEnabled()) {
1720                        logger.debug("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
1721                }
1722
1723                if (System.getSecurityManager() != null) {
1724                        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
1725                                @Override
1726                                public Object run() throws Exception {
1727                                        ReflectionUtils.makeAccessible(initMethod);
1728                                        return null;
1729                                }
1730                        });
1731                        try {
1732                                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
1733                                        @Override
1734                                        public Object run() throws Exception {
1735                                                initMethod.invoke(bean);
1736                                                return null;
1737                                        }
1738                                }, getAccessControlContext());
1739                        }
1740                        catch (PrivilegedActionException pae) {
1741                                InvocationTargetException ex = (InvocationTargetException) pae.getException();
1742                                throw ex.getTargetException();
1743                        }
1744                }
1745                else {
1746                        try {
1747                                ReflectionUtils.makeAccessible(initMethod);
1748                                initMethod.invoke(bean);
1749                        }
1750                        catch (InvocationTargetException ex) {
1751                                throw ex.getTargetException();
1752                        }
1753                }
1754        }
1755
1756
1757        /**
1758         * Applies the {@code postProcessAfterInitialization} callback of all
1759         * registered BeanPostProcessors, giving them a chance to post-process the
1760         * object obtained from FactoryBeans (for example, to auto-proxy them).
1761         * @see #applyBeanPostProcessorsAfterInitialization
1762         */
1763        @Override
1764        protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
1765                return applyBeanPostProcessorsAfterInitialization(object, beanName);
1766        }
1767
1768        /**
1769         * Overridden to clear FactoryBean instance cache as well.
1770         */
1771        @Override
1772        protected void removeSingleton(String beanName) {
1773                synchronized (getSingletonMutex()) {
1774                        super.removeSingleton(beanName);
1775                        this.factoryBeanInstanceCache.remove(beanName);
1776                }
1777        }
1778
1779        /**
1780         * Overridden to clear FactoryBean instance cache as well.
1781         */
1782        @Override
1783        protected void clearSingletonCache() {
1784                synchronized (getSingletonMutex()) {
1785                        super.clearSingletonCache();
1786                        this.factoryBeanInstanceCache.clear();
1787                }
1788        }
1789
1790
1791        /**
1792         * Special DependencyDescriptor variant for Spring's good old autowire="byType" mode.
1793         * Always optional; never considering the parameter name for choosing a primary candidate.
1794         */
1795        @SuppressWarnings("serial")
1796        private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor {
1797
1798                public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) {
1799                        super(methodParameter, false, eager);
1800                }
1801
1802                @Override
1803                public String getDependencyName() {
1804                        return null;
1805                }
1806        }
1807
1808}