List of usage examples for org.springframework.beans.factory.support RootBeanDefinition getFactoryBeanName
@Override
@Nullable
public String getFactoryBeanName()
From source file:com.gwtplatform.dispatch.rpc.server.spring.utils.SpringUtils.java
private static String generateName(ConfigurableListableBeanFactory registry, RootBeanDefinition definition) { String generatedBeanName = definition.getBeanClassName(); if (generatedBeanName == null) { if (definition.getParentName() != null) { generatedBeanName = definition.getParentName() + "$child"; } else if (definition.getFactoryBeanName() != null) { generatedBeanName = definition.getFactoryBeanName() + "$created"; }//from w w w . ja v a 2 s . com } if (!StringUtils.hasText(generatedBeanName)) { throw new BeanDefinitionStoreException( "Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean' - can't " + "generate bean name"); } String id = generatedBeanName; // Top-level bean: use plain class name. // Increase counter until the id is unique. int counter = -1; while (counter == -1 || (registry.containsSingleton(id))) { counter++; id = generatedBeanName + "#" + counter; } return id; }
From source file:com.gwtplatform.dispatch.server.spring.utils.SpringUtils.java
private static String generateName(ConfigurableListableBeanFactory registry, RootBeanDefinition definition) { String generatedBeanName = definition.getBeanClassName(); if (generatedBeanName == null) { if (definition.getParentName() != null) { generatedBeanName = definition.getParentName() + "$child"; } else if (definition.getFactoryBeanName() != null) { generatedBeanName = definition.getFactoryBeanName() + "$created"; }// w w w . j a va 2s . c o m } if (!StringUtils.hasText(generatedBeanName)) { throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " + "'class' nor 'parent' nor 'factory-bean' - can't generate bean name"); } String id = generatedBeanName; // Top-level bean: use plain class name. // Increase counter until the id is unique. int counter = -1; while (counter == -1 || (registry.containsSingleton(id))) { counter++; id = generatedBeanName + "#" + counter; } return id; }
From source file:com.longio.spring.LioBootstrap.java
private void bootEndpoints(DefaultListableBeanFactory bf, String name) { RootBeanDefinition bd = (RootBeanDefinition) bf.getBeanDefinition(name); String fbMethod = bd.getFactoryMethodName(); String fbName = bd.getFactoryBeanName(); Object fb = bf.getBean(fbName); if (!bf.containsBeanDefinition("longio.connector")) { GenericBeanDefinition bdd = new GenericBeanDefinition(); bdd.setBeanClass(NettyConnector.class); bf.registerBeanDefinition("longio.connector", bdd); }//from w w w . j a v a2s . co m Connector connector = bf.getBean("longio.connector", Connector.class); Class<?> fbCls = fb.getClass().getSuperclass(); Method m; try { m = fbCls.getDeclaredMethod(fbMethod); Boots boots = m.getAnnotation(Boots.class); if (boots == null) { MethodDispatcher dispatcher = new MethodDispatcher(); Boot b = m.getAnnotation(Boot.class); connector.start(b.port(), dispatcher, b.tt(), b.pt(), b.pkg()); logger.info("connector start at port [" + b.port() + "] with tt = " + b.tt() + " and pt = " + b.pt() + " for pkg = " + b.pkg()); } else { for (Boot b : boots.value()) { MethodDispatcher dispatcher = new MethodDispatcher(); connector.start(b.port(), dispatcher, b.tt(), b.pt(), b.pkg()); logger.info("connector start at port [" + b.port() + "] with tt = " + b.tt() + " and pt = " + b.pt() + " for pkg = " + b.pkg()); } } } catch (Exception e) { e.printStackTrace(); } }
From source file:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.java
/** * Determine the target type for the given bean definition which is based on * a factory method. Only called if there is no singleton instance registered * for the target bean already./*from w ww. j ava 2 s . c om*/ * <p>This implementation determines the type matching {@link #createBean}'s * different creation strategies. As far as possible, we'll perform static * type checking to avoid creation of the target bean. * @param beanName the name of the bean (for error handling purposes) * @param mbd the merged bean definition for the bean * @param typesToMatch the types to match in case of internal type matching purposes * (also signals that the returned {@code Class} will never be exposed to application code) * @return the type for the bean if determinable, or {@code null} otherwise * @see #createBean */ @Nullable protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { ResolvableType cachedReturnType = mbd.factoryMethodReturnType; if (cachedReturnType != null) { return cachedReturnType.resolve(); } Class<?> factoryClass; boolean isStatic = true; 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"); } // Check declared factory method return type on factory class. factoryClass = getType(factoryBeanName); isStatic = false; } else { // Check declared factory method return type on bean class. factoryClass = resolveBeanClass(mbd, beanName, typesToMatch); } if (factoryClass == null) { return null; } factoryClass = ClassUtils.getUserClass(factoryClass); // If all factory methods have the same return type, return that type. // Can't clearly figure out exact method due to type converting / autowiring! Class<?> commonType = null; Method uniqueCandidate = null; int minNrOfArgs = (mbd.hasConstructorArgumentValues() ? mbd.getConstructorArgumentValues().getArgumentCount() : 0); Method[] candidates = this.factoryMethodCandidateCache.computeIfAbsent(factoryClass, ReflectionUtils::getUniqueDeclaredMethods); for (Method candidate : candidates) { if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) && candidate.getParameterCount() >= minNrOfArgs) { // Declared type variables to inspect? if (candidate.getTypeParameters().length > 0) { try { // Fully resolve parameter names and argument values. Class<?>[] paramTypes = candidate.getParameterTypes(); String[] paramNames = null; ParameterNameDiscoverer pnd = getParameterNameDiscoverer(); if (pnd != null) { paramNames = pnd.getParameterNames(candidate); } ConstructorArgumentValues cav = mbd.getConstructorArgumentValues(); Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>( paramTypes.length); Object[] args = new Object[paramTypes.length]; for (int i = 0; i < args.length; i++) { ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders); if (valueHolder == null) { valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders); } if (valueHolder != null) { args[i] = valueHolder.getValue(); usedValueHolders.add(valueHolder); } } Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(candidate, args, getBeanClassLoader()); uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ? candidate : null); commonType = ClassUtils.determineCommonAncestor(returnType, commonType); if (commonType == null) { // Ambiguous return types found: return null to indicate "not determinable". return null; } } catch (Throwable ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to resolve generic return type for factory method: " + ex); } } } else { uniqueCandidate = (commonType == null ? candidate : null); commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType); if (commonType == null) { // Ambiguous return types found: return null to indicate "not determinable". return null; } } } } if (commonType == null) { return null; } // Common return type found: all factory methods return same type. For a non-parameterized // unique candidate, cache the full type declaration context of the target factory method. cachedReturnType = (uniqueCandidate != null ? ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType)); mbd.factoryMethodReturnType = cachedReturnType; return cachedReturnType.resolve(); }
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. jav a2 s. c o 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.AbstractAutowireCapableBeanFactory.java
/** * Obtain a "shortcut" singleton FactoryBean instance to use for a * {@code getObjectType()} call, without full initialization of the FactoryBean. * @param beanName the name of the bean// w w w. java 2 s.co m * @param mbd the bean definition for the bean * @return the FactoryBean instance, or {@code null} to indicate * that we couldn't obtain a shortcut FactoryBean instance */ @Nullable private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) { synchronized (getSingletonMutex()) { BeanWrapper bw = this.factoryBeanInstanceCache.get(beanName); if (bw != null) { return (FactoryBean<?>) bw.getWrappedInstance(); } Object beanInstance = getSingleton(beanName, false); if (beanInstance instanceof FactoryBean) { return (FactoryBean<?>) beanInstance; } if (isSingletonCurrentlyInCreation(beanName) || (mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) { return null; } Object instance; try { // Mark this bean as currently in creation, even if just partially. beforeSingletonCreation(beanName); // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. instance = resolveBeforeInstantiation(beanName, mbd); if (instance == null) { bw = createBeanInstance(beanName, mbd, null); instance = bw.getWrappedInstance(); } } finally { // Finished partial creation of this bean. afterSingletonCreation(beanName); } FactoryBean<?> fb = getFactoryBean(beanName, instance); if (bw != null) { this.factoryBeanInstanceCache.put(beanName, bw); } return fb; } }
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 *///from w w w .j a v a2 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/*from w ww.j a va2s.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); } }