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

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

Introduction

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

Prototype

public Class<?> getBeanClass() throws IllegalStateException 

Source Link

Document

Return the class of the wrapped bean (assuming it is resolved already).

Usage

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 ww w  . j ava  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

public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    Class beanClass = null;/*  w w w . ja v a2  s  . co  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

public Class getType(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    try {/*from   w  w  w  .jav a2s .  co  m*/
        Class beanClass = null;

        // Check manually registered singletons.
        Object beanInstance = null;
        synchronized (this.singletonCache) {
            beanInstance = this.singletonCache.get(beanName);
        }
        if (beanInstance != null) {
            beanClass = beanInstance.getClass();
        }

        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().getType(name);
            }

            RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);

            // Delegate to getTypeForFactoryMethod in case of factory method.
            if (mergedBeanDefinition.getFactoryMethodName() != null) {
                return getTypeForFactoryMethod(name, mergedBeanDefinition);
            }
            // Return "undeterminable" for beans without class.
            if (!mergedBeanDefinition.hasBeanClass()) {
                return null;
            }

            beanClass = mergedBeanDefinition.getBeanClass();
        }

        // Check bean class whether we're dealing with a FactoryBean.
        if (FactoryBean.class.isAssignableFrom(beanClass) && !isFactoryDereference(name)) {
            // If it's a FactoryBean, we want to look at what it creates, not the factory class.
            FactoryBean factoryBean = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
            return factoryBean.getObjectType();
        }
        return beanClass;
    }

    catch (BeanCreationException ex) {
        if (ex.contains(BeanCurrentlyInCreationException.class)
                || ex.contains(FactoryBeanNotInitializedException.class)) {
            // Can only happen when checking a FactoryBean.
            logger.debug("Ignoring BeanCreationException on FactoryBean type check", ex);
            return null;
        }
        throw ex;
    }
}

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   w  ww .  j  a va  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

/**
 * Determine whether the bean with the given name is a FactoryBean.
 * @param name the name of the bean to check
 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
 *//*from ww w  .  j a  v a  2 s.c  o  m*/
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);

    synchronized (this.singletonCache) {
        Object beanInstance = this.singletonCache.get(beanName);
        if (beanInstance != null) {
            return (beanInstance instanceof FactoryBean);
        }
    }

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

    RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
    return (bd.hasBeanClass() && FactoryBean.class.equals(bd.getBeanClass()));
}

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

/**
 * "autowire constructor" (with constructor arguments by type) behavior.
 * Also applied if explicit constructor argument values are specified,
 * matching all remaining arguments with beans from the bean factory.
 * <p>This corresponds to constructor injection: In this mode, a Spring
 * bean factory is able to host components that expect constructor-based
 * dependency resolution./*from  w  w  w.  j a va  2s. c o m*/
 * @param beanName the name of the bean
 * @param mbd the merged bean definition for the bean
 * @param chosenCtors chosen candidate constructors (or {@code null} if none)
 * @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 autowireConstructor(final String beanName, final RootBeanDefinition mbd,
        @Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {

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

    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // Found a cached constructor...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        if (argsToResolve != null) {
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
        }
    }

    if (constructorToUse == null) {
        // Need to resolve the constructor.
        boolean autowiring = (chosenCtors != null
                || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;

        int minNrOfArgs;
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        } else {
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        // Take specified constructors, if any.
        Constructor<?>[] candidates = chosenCtors;
        if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
                candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors()
                        : beanClass.getConstructors());
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Resolution of declared constructors on bean Class [" + beanClass.getName()
                                + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed",
                        ex);
            }
        }
        AutowireUtils.sortConstructors(candidates);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        LinkedList<UnsatisfiedDependencyException> causes = null;

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

            if (constructorToUse != null && argsToUse.length > paramTypes.length) {
                // Already found greedy constructor that can be satisfied ->
                // do not look any further, there are only less greedy constructors left.
                break;
            }
            if (paramTypes.length < minNrOfArgs) {
                continue;
            }

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

            int typeDiffWeight = (mbd.isLenientConstructorResolution()
                    ? argsHolder.getTypeDifferenceWeight(paramTypes)
                    : argsHolder.getAssignabilityWeight(paramTypes));
            // Choose this constructor if it represents the closest match.
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }

        if (constructorToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Could not resolve matching constructor "
                            + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
        } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous constructor matches found in bean '" + beanName + "' "
                            + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): "
                            + ambiguousConstructors);
        }

        if (explicitArgs == null) {
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    try {
        final InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
        Object beanInstance;

        if (System.getSecurityManager() != null) {
            final Constructor<?> ctorToUse = constructorToUse;
            final Object[] argumentsToUse = argsToUse;
            beanInstance = AccessController
                    .doPrivileged(
                            (PrivilegedAction<Object>) () -> strategy.instantiate(mbd, beanName,
                                    this.beanFactory, ctorToUse, argumentsToUse),
                            this.beanFactory.getAccessControlContext());
        } else {
            beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
        }

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

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

/**
 * Resolve the factory method in the specified bean definition, if possible.
 * {@link RootBeanDefinition#getResolvedFactoryMethod()} can be checked for the result.
 * @param mbd the bean definition to check
 *///  w  w w  . ja  va  2  s  . c o  m
public void resolveFactoryMethodIfPossible(RootBeanDefinition mbd) {
    Class<?> factoryClass;
    boolean isStatic;
    if (mbd.getFactoryBeanName() != null) {
        factoryClass = this.beanFactory.getType(mbd.getFactoryBeanName());
        isStatic = false;
    } else {
        factoryClass = mbd.getBeanClass();
        isStatic = true;
    }
    Assert.state(factoryClass != null, "Unresolvable factory class");
    factoryClass = ClassUtils.getUserClass(factoryClass);

    Method[] candidates = getCandidateMethods(factoryClass, mbd);
    Method uniqueCandidate = null;
    for (Method candidate : candidates) {
        if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
            if (uniqueCandidate == null) {
                uniqueCandidate = candidate;
            } else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParameterTypes())) {
                uniqueCandidate = null;
                break;
            }
        }
    }
    synchronized (mbd.constructorArgumentLock) {
        mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
    }
}

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 av  a2 s  .  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.beans.factory.support.SimpleInstantiationStrategy.java

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

    // Don't override the class with CGLIB if no overrides.
    if (beanDefinition.getMethodOverrides().isEmpty()) {
        return BeanUtils.instantiateClass(beanDefinition.getBeanClass());
    } else {/*ww  w. j av  a 2s  .  co  m*/
        // Must generate CGLIB subclass.
        return instantiateWithMethodInjection(beanDefinition, beanName, owner);
    }
}