Example usage for org.springframework.beans.factory.support RootBeanDefinition isSingleton

List of usage examples for org.springframework.beans.factory.support RootBeanDefinition isSingleton

Introduction

In this page you can find the example usage for org.springframework.beans.factory.support RootBeanDefinition isSingleton.

Prototype

@Override
public boolean isSingleton() 

Source Link

Document

Return whether this a Singleton, with a single shared instance returned from all calls.

Usage

From source file:org.sakaiproject.util.NoisierDefaultListableBeanFactory.java

public void preInstantiateSingletons() throws BeansException {
    if (logger.isDebugEnabled()) {
        logger.debug("Pre-instantiating singletons in factory [" + this + "]");
    }/* w  ww  .  ja v  a 2s  .  c  o  m*/

    // The superclass's variable by this name is declared private.
    String[] beanDefinitionNames = getBeanDefinitionNames();
    String beanName = null; // Remember in case of an exception
    try {
        //         for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
        for (int i = 0; i < beanDefinitionNames.length; i++) {
            beanName = beanDefinitionNames[i];
            if (!containsSingleton(beanName) && containsBeanDefinition(beanName)) {
                RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
                if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                    if (bd.hasBeanClass() && FactoryBean.class.isAssignableFrom(bd.getBeanClass())) {
                        FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                        if (factory.isSingleton()) {
                            getBean(beanName);
                        }
                    } else {
                        getBean(beanName);
                    }
                }
            }
        }
    } catch (BeansException ex) {
        // Destroy already created singletons to avoid dangling resources.
        logger.error(
                "Failed to preinstantiate the singleton named " + beanName + ". Destroying all Spring beans.",
                ex);
        try {
            destroySingletons();
        } catch (Throwable ex2) {
            logger.error(
                    "Pre-instantiating singletons failed, " + "and couldn't destroy already created singletons",
                    ex2);
        }
        throw ex;
    }
}

From source file:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.java

/**
 * Actually create the specified bean. Pre-creation processing has already happened
 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
 * <p>Differentiates between default bean instantiation, use of a
 * factory method, and autowiring a constructor.
 * @param beanName the name of the bean/*w ww. j  a v  a2  s  .c om*/
 * @param mbd the merged bean definition for the bean
 * @param args explicit arguments to use for constructor or factory method invocation
 * @return a new instance of the bean
 * @throws BeanCreationException if the bean could not be created
 * @see #instantiateBean
 * @see #instantiateUsingFactoryMethod
 * @see #autowireConstructor
 */
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
        final @Nullable Object[] args) throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences
            && isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName
                    + "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException
                && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Initialization of bean failed", ex);
        }
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName
                            + "' has been injected into other beans ["
                            + StringUtils.collectionToCommaDelimitedString(actualDependentBeans)
                            + "] in its raw version as part of a circular reference, but has eventually been "
                            + "wrapped. This means that said other beans do not use the final version of the "
                            + "bean. This is often the result of over-eager type matching - consider using "
                            + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature",
                ex);
    }

    return exposedObject;
}

From source file:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.java

/**
 * This implementation attempts to query the FactoryBean's generic parameter metadata
 * if present to determine the object type. If not present, i.e. the FactoryBean is
 * declared as a raw type, checks the FactoryBean's {@code getObjectType} method
 * on a plain instance of the FactoryBean, without bean properties applied yet.
 * If this doesn't return a type yet, a full creation of the FactoryBean is
 * used as fallback (through delegation to the superclass's implementation).
 * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
 * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
 * it will be fully created to check the type of its exposed object.
 *///from  w  ww.ja  v  a 2 s  . co m
@Override
@Nullable
protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
    if (mbd.getInstanceSupplier() != null) {
        ResolvableType targetType = mbd.targetType;
        if (targetType != null) {
            Class<?> result = targetType.as(FactoryBean.class).getGeneric().resolve();
            if (result != null) {
                return result;
            }
        }
        if (mbd.hasBeanClass()) {
            Class<?> result = GenericTypeResolver.resolveTypeArgument(mbd.getBeanClass(), FactoryBean.class);
            if (result != null) {
                return result;
            }
        }
    }

    String factoryBeanName = mbd.getFactoryBeanName();
    String factoryMethodName = mbd.getFactoryMethodName();

    if (factoryBeanName != null) {
        if (factoryMethodName != null) {
            // Try to obtain the FactoryBean's object type from its factory method declaration
            // without instantiating the containing bean at all.
            BeanDefinition fbDef = getBeanDefinition(factoryBeanName);
            if (fbDef instanceof AbstractBeanDefinition) {
                AbstractBeanDefinition afbDef = (AbstractBeanDefinition) fbDef;
                if (afbDef.hasBeanClass()) {
                    Class<?> result = getTypeForFactoryBeanFromMethod(afbDef.getBeanClass(), factoryMethodName);
                    if (result != null) {
                        return result;
                    }
                }
            }
        }
        // If not resolvable above and the referenced factory bean doesn't exist yet,
        // exit here - we don't want to force the creation of another bean just to
        // obtain a FactoryBean's object type...
        if (!isBeanEligibleForMetadataCaching(factoryBeanName)) {
            return null;
        }
    }

    // Let's obtain a shortcut instance for an early getObjectType() call...
    FactoryBean<?> fb = (mbd.isSingleton() ? getSingletonFactoryBeanForTypeCheck(beanName, mbd)
            : getNonSingletonFactoryBeanForTypeCheck(beanName, mbd));

    if (fb != null) {
        // Try to obtain the FactoryBean's object type from this early stage of the instance.
        Class<?> result = getTypeForFactoryBean(fb);
        if (result != null) {
            return result;
        } else {
            // No type found for shortcut FactoryBean instance:
            // fall back to full creation of the FactoryBean instance.
            return super.getTypeForFactoryBean(beanName, mbd);
        }
    }

    if (factoryBeanName == null && mbd.hasBeanClass()) {
        // No early bean instantiation possible: determine FactoryBean's type from
        // static factory method signature or from class inheritance hierarchy...
        if (factoryMethodName != null) {
            return getTypeForFactoryBeanFromMethod(mbd.getBeanClass(), factoryMethodName);
        } else {
            return GenericTypeResolver.resolveTypeArgument(mbd.getBeanClass(), FactoryBean.class);
        }
    }

    return null;
}

From source file:org.springframework.beans.factory.support.AbstractBeanFactory.java

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use if creating a prototype using explicit arguments to a
 * static factory method. It is invalid to use a non-null args value in any other case.
 * @return an instance of the bean/*  w ww  . ja v  a 2  s  .co m*/
 * @throws BeansException if the bean could not be created
 */
public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
    String beanName = transformedBeanName(name);
    Object bean = null;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = null;
    synchronized (this.singletonCache) {
        sharedInstance = this.singletonCache.get(beanName);
    }
    if (sharedInstance != null) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName
                        + "' that is not fully initialized yet - a consequence of a circular reference");
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        bean = getObjectForSharedInstance(name, sharedInstance);
    }

    else {
        // Fail if we're already creating this singleton instance:
        // We're assumably within a circular reference.
        if (isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        if (getParentBeanFactory() != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            if (getParentBeanFactory() instanceof AbstractBeanFactory) {
                // Delegation to parent with args only possible for AbstractBeanFactory.
                return ((AbstractBeanFactory) getParentBeanFactory()).getBean(name, requiredType, args);
            } else if (args == null) {
                // No args -> delegate to standard getBean method.
                return getParentBeanFactory().getBean(name, requiredType);
            } else {
                throw new NoSuchBeanDefinitionException(beanName,
                        "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments");
            }
        }

        RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
        checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args);

        // Create bean instance.
        if (mergedBeanDefinition.isSingleton()) {
            synchronized (this.singletonCache) {
                // Re-check singleton cache within synchronized block.
                sharedInstance = this.singletonCache.get(beanName);
                if (sharedInstance == null) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                    }
                    this.currentlyInCreation.add(beanName);
                    try {
                        sharedInstance = createBean(beanName, mergedBeanDefinition, args);
                        addSingleton(beanName, sharedInstance);
                    } catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroyDisposableBean(beanName);
                        throw ex;
                    } finally {
                        this.currentlyInCreation.remove(beanName);
                    }
                }
            }
            bean = getObjectForSharedInstance(name, sharedInstance);
        } else {
            // It's a prototype -> create a new instance.
            bean = createBean(beanName, mergedBeanDefinition, args);
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
        throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    return bean;
}

From source file:org.springframework.beans.factory.support.AbstractBeanFactory.java

public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    Class beanClass = null;/*from w ww .  j a  va 2 s  .  c  o m*/
    boolean singleton = true;

    Object beanInstance = null;
    synchronized (this.singletonCache) {
        beanInstance = this.singletonCache.get(beanName);
    }

    if (beanInstance != null) {
        beanClass = beanInstance.getClass();
        singleton = true;
    }

    else {
        // No singleton instance found -> check bean definition.
        if (getParentBeanFactory() != null && !containsBeanDefinition(beanName)) {
            // No bean definition found in this factory -> delegate to parent.
            return getParentBeanFactory().isSingleton(name);
        }

        RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
        if (bd.hasBeanClass()) {
            beanClass = bd.getBeanClass();
        }
        singleton = bd.isSingleton();
    }

    // In case of FactoryBean, return singleton status of created object if not a dereference.
    if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass) && !isFactoryDereference(name)) {
        FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
        return factoryBean.isSingleton();
    }

    return singleton;
}

From source file:org.springframework.beans.factory.support.AbstractBeanFactory.java

/**
 * Check the given merged bean definition,
 * potentially throwing validation exceptions.
 * @param mergedBeanDefinition the bean definition to check
 * @param beanName the name of the bean//from   www  . j  a v a  2  s.c  o m
 * @param requiredType the required type of the bean
 * @param args the arguments for bean creation, if any
 * @throws BeansException in case of validation failure
 */
protected void checkMergedBeanDefinition(RootBeanDefinition mergedBeanDefinition, String beanName,
        Class requiredType, Object[] args) throws BeansException {

    // check if bean definition is not abstract
    if (mergedBeanDefinition.isAbstract()) {
        throw new BeanIsAbstractException(beanName);
    }

    // Check if required type can match according to the bean definition.
    // This is only possible at this early stage for conventional beans!
    if (mergedBeanDefinition.hasBeanClass()) {
        Class beanClass = mergedBeanDefinition.getBeanClass();
        if (requiredType != null && mergedBeanDefinition.getFactoryMethodName() == null
                && !FactoryBean.class.isAssignableFrom(beanClass)
                && !requiredType.isAssignableFrom(beanClass)) {
            throw new BeanNotOfRequiredTypeException(beanName, requiredType, beanClass);
        }
    }

    // Check validity of the usage of the args parameter. This can
    // only be used for prototypes constructed via a factory method.
    if (args != null) {
        if (mergedBeanDefinition.isSingleton()) {
            throw new BeanDefinitionStoreException(
                    "Cannot specify arguments in the getBean() method when referring to a singleton bean definition");
        } else if (mergedBeanDefinition.getFactoryMethodName() == null) {
            throw new BeanDefinitionStoreException(
                    "Can only specify arguments in the getBean() method in conjunction with a factory method");
        }
    }
}

From source file:org.springframework.beans.factory.support.AbstractBeanFactory.java

/**
 * Add the given bean to the list of disposable beans in this factory,
 * registering its DisposableBean interface and/or the given destroy method
 * to be called on factory shutdown (if applicable). Only applies to singletons.
 * <p>Also registers bean as dependent on other beans, according to the
 * "depends-on" configuration in the bean definition.
 * @param beanName the name of the bean/*  w  w w  . j  a  v a 2s . c o m*/
 * @param bean the bean instance
 * @param mergedBeanDefinition the bean definition for the bean
 * @see RootBeanDefinition#isSingleton
 * @see RootBeanDefinition#getDependsOn
 * @see #registerDisposableBean
 * @see #registerDependentBean
 */
protected void registerDisposableBeanIfNecessary(final String beanName, final Object bean,
        final RootBeanDefinition mergedBeanDefinition) {

    if (mergedBeanDefinition.isSingleton()) {
        final boolean isDisposableBean = (bean instanceof DisposableBean);
        final boolean hasDestroyMethod = (mergedBeanDefinition.getDestroyMethodName() != null);

        if (isDisposableBean || hasDestroyMethod || hasDestructionAwareBeanPostProcessors()) {
            // Determine unique key for registration of disposable bean
            int counter = 1;
            String id = beanName;
            synchronized (this.disposableBeans) {
                while (this.disposableBeans.containsKey(id)) {
                    counter++;
                    id = beanName + "#" + counter;
                }
            }

            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.

            registerDisposableBean(id, new DisposableBean() {
                public void destroy() throws Exception {

                    if (hasDestructionAwareBeanPostProcessors()) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Applying DestructionAwareBeanPostProcessors to bean with name '"
                                    + beanName + "'");
                        }
                        for (int i = getBeanPostProcessors().size() - 1; i >= 0; i--) {
                            Object beanProcessor = getBeanPostProcessors().get(i);
                            if (beanProcessor instanceof DestructionAwareBeanPostProcessor) {
                                ((DestructionAwareBeanPostProcessor) beanProcessor)
                                        .postProcessBeforeDestruction(bean, beanName);
                            }
                        }
                    }

                    if (isDisposableBean) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Invoking destroy() on bean with name '" + beanName + "'");
                        }
                        ((DisposableBean) bean).destroy();
                    }

                    if (hasDestroyMethod) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Invoking custom destroy method on bean with name '" + beanName + "'");
                        }
                        invokeCustomDestroyMethod(beanName, bean, mergedBeanDefinition.getDestroyMethodName(),
                                mergedBeanDefinition.isEnforceDestroyMethod());
                    }
                }
            });
        }

        // Register bean as dependent on other beans, if necessary,
        // for correct shutdown order.
        String[] dependsOn = mergedBeanDefinition.getDependsOn();
        if (dependsOn != null) {
            for (int i = 0; i < dependsOn.length; i++) {
                registerDependentBean(dependsOn[i], beanName);
            }
        }
    }
}

From source file:org.springframework.beans.factory.support.BeanDefinitionValueResolver.java

/**
 * Resolve an inner bean definition./*from ww w.  j  a  v  a2  s  . c o m*/
 */
private Object resolveInnerBeanDefinition(String argName, String innerBeanName, BeanDefinition innerBd)
        throws BeansException {

    if (logger.isDebugEnabled()) {
        logger.debug("Resolving inner bean definition '" + innerBeanName + "' of bean '" + this.beanName + "'");
    }
    try {
        RootBeanDefinition mergedInnerBd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd);
        Object innerBean = this.beanFactory.createBean(innerBeanName, mergedInnerBd, null);
        if (mergedInnerBd.isSingleton()) {
            this.beanFactory.registerDependentBean(innerBeanName, this.beanName);
        }
        return this.beanFactory.getObjectForSharedInstance(innerBeanName, innerBean);
    } catch (BeansException ex) {
        throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,
                "Cannot create inner bean '" + innerBeanName + "' while setting " + argName, ex);
    }
}

From source file:org.springframework.beans.factory.support.ConstructorResolver.java

/**
 * Instantiate the bean using a named factory method. The method may be static, if the
 * bean definition parameter specifies a class, rather than a "factory-bean", or
 * an instance variable on a factory object itself configured using Dependency Injection.
 * <p>Implementation requires iterating over the static or instance methods with the
 * name specified in the RootBeanDefinition (the method may be overloaded) and trying
 * to match with the parameters. We don't have the types attached to constructor args,
 * so trial and error is the only way to go here. The explicitArgs array may contain
 * argument values passed in programmatically via the corresponding getBean method.
 * @param beanName the name of the bean//  w w  w .j  a  v a 2s  .c  o m
 * @param mbd the merged bean definition for the bean
 * @param explicitArgs argument values passed in programmatically via the getBean
 * method, or {@code null} if none (-> use constructor argument values from bean definition)
 * @return a BeanWrapper for the new instance
 */
public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final RootBeanDefinition mbd,
        @Nullable final Object[] explicitArgs) {

    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

    Object factoryBean;
    Class<?> factoryClass;
    boolean isStatic;

    String factoryBeanName = mbd.getFactoryBeanName();
    if (factoryBeanName != null) {
        if (factoryBeanName.equals(beanName)) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                    "factory-bean reference points back to the same bean definition");
        }
        factoryBean = this.beanFactory.getBean(factoryBeanName);
        if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
            throw new ImplicitlyAppearedSingletonException();
        }
        factoryClass = factoryBean.getClass();
        isStatic = false;
    } else {
        // It's a static factory method on the bean class.
        if (!mbd.hasBeanClass()) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                    "bean definition declares neither a bean class nor a factory-bean reference");
        }
        factoryBean = null;
        factoryClass = mbd.getBeanClass();
        isStatic = true;
    }

    Method factoryMethodToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
            if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
                // Found a cached factory method...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        if (argsToResolve != null) {
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
        }
    }

    if (factoryMethodToUse == null || argsToUse == null) {
        // Need to determine the factory method...
        // Try all methods with this name to see if they match the given arguments.
        factoryClass = ClassUtils.getUserClass(factoryClass);

        Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
        List<Method> candidateSet = new ArrayList<>();
        for (Method candidate : rawCandidates) {
            if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
                candidateSet.add(candidate);
            }
        }
        Method[] candidates = candidateSet.toArray(new Method[0]);
        AutowireUtils.sortFactoryMethods(candidates);

        ConstructorArgumentValues resolvedValues = null;
        boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Method> ambiguousFactoryMethods = null;

        int minNrOfArgs;
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        } else {
            // We don't have arguments passed in programmatically, so we need to resolve the
            // arguments specified in the constructor arguments held in the bean definition.
            if (mbd.hasConstructorArgumentValues()) {
                ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                resolvedValues = new ConstructorArgumentValues();
                minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
            } else {
                minNrOfArgs = 0;
            }
        }

        LinkedList<UnsatisfiedDependencyException> causes = null;

        for (Method candidate : candidates) {
            Class<?>[] paramTypes = candidate.getParameterTypes();

            if (paramTypes.length >= minNrOfArgs) {
                ArgumentsHolder argsHolder;

                if (explicitArgs != null) {
                    // Explicit arguments given -> arguments length must match exactly.
                    if (paramTypes.length != explicitArgs.length) {
                        continue;
                    }
                    argsHolder = new ArgumentsHolder(explicitArgs);
                } else {
                    // Resolved constructor arguments: type conversion and/or autowiring necessary.
                    try {
                        String[] paramNames = null;
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            paramNames = pnd.getParameterNames(candidate);
                        }
                        argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes,
                                paramNames, candidate, autowiring, candidates.length == 1);
                    } catch (UnsatisfiedDependencyException ex) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName
                                    + "': " + ex);
                        }
                        // Swallow and try next overloaded factory method.
                        if (causes == null) {
                            causes = new LinkedList<>();
                        }
                        causes.add(ex);
                        continue;
                    }
                }

                int typeDiffWeight = (mbd.isLenientConstructorResolution()
                        ? argsHolder.getTypeDifferenceWeight(paramTypes)
                        : argsHolder.getAssignabilityWeight(paramTypes));
                // Choose this factory method if it represents the closest match.
                if (typeDiffWeight < minTypeDiffWeight) {
                    factoryMethodToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousFactoryMethods = null;
                }
                // Find out about ambiguity: In case of the same type difference weight
                // for methods with the same number of parameters, collect such candidates
                // and eventually raise an ambiguity exception.
                // However, only perform that check in non-lenient constructor resolution mode,
                // and explicitly ignore overridden methods (with the same parameter signature).
                else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight
                        && !mbd.isLenientConstructorResolution()
                        && paramTypes.length == factoryMethodToUse.getParameterCount()
                        && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
                    if (ambiguousFactoryMethods == null) {
                        ambiguousFactoryMethods = new LinkedHashSet<>();
                        ambiguousFactoryMethods.add(factoryMethodToUse);
                    }
                    ambiguousFactoryMethods.add(candidate);
                }
            }
        }

        if (factoryMethodToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            List<String> argTypes = new ArrayList<>(minNrOfArgs);
            if (explicitArgs != null) {
                for (Object arg : explicitArgs) {
                    argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
                }
            } else if (resolvedValues != null) {
                Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
                valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
                valueHolders.addAll(resolvedValues.getGenericArgumentValues());
                for (ValueHolder value : valueHolders) {
                    String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType())
                            : (value.getValue() != null ? value.getValue().getClass().getSimpleName()
                                    : "null"));
                    argTypes.add(argType);
                }
            }
            String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "No matching factory method found: "
                            + (mbd.getFactoryBeanName() != null
                                    ? "factory bean '" + mbd.getFactoryBeanName() + "'; "
                                    : "")
                            + "factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. "
                            + "Check that a method with the specified name "
                            + (minNrOfArgs > 0 ? "and arguments " : "") + "exists and that it is "
                            + (isStatic ? "static" : "non-static") + ".");
        } else if (void.class == factoryMethodToUse.getReturnType()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid factory method '"
                    + mbd.getFactoryMethodName() + "': needs to have a non-void return type!");
        } else if (ambiguousFactoryMethods != null) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous factory method matches found in bean '" + beanName + "' "
                            + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): "
                            + ambiguousFactoryMethods);
        }

        if (explicitArgs == null && argsHolderToUse != null) {
            argsHolderToUse.storeCache(mbd, factoryMethodToUse);
        }
    }

    try {
        Object beanInstance;

        if (System.getSecurityManager() != null) {
            final Object fb = factoryBean;
            final Method factoryMethod = factoryMethodToUse;
            final Object[] args = argsToUse;
            beanInstance = AccessController.doPrivileged(
                    (PrivilegedAction<Object>) () -> this.beanFactory.getInstantiationStrategy()
                            .instantiate(mbd, beanName, this.beanFactory, fb, factoryMethod, args),
                    this.beanFactory.getAccessControlContext());
        } else {
            beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName,
                    this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
        }

        bw.setBeanInstance(beanInstance);
        return bw;
    } catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean instantiation via factory method failed", ex);
    }
}

From source file:org.springframework.context.support.ApplicationListenerDetector.java

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType,
        String beanName) {//from   w  w w.  jav a2s  . com
    this.singletonNames.put(beanName, beanDefinition.isSingleton());
}