List of usage examples for org.springframework.util ClassUtils determineCommonAncestor
@Nullable public static Class<?> determineCommonAncestor(@Nullable Class<?> clazz1, @Nullable Class<?> clazz2)
From source file:org.agatom.springatom.data.oid.impl.SOidServiceImpl.java
private SOidCreator<?> getCreator(final Class<?> clazz) { final Optional<OidCreatorKey> match = FluentIterable.from(this.oidCreatorsMap.keySet()) .firstMatch(new Predicate<OidCreatorKey>() { @Override//from w w w . j a va2s. co m public boolean apply(@Nullable final OidCreatorKey input) { assert input != null; final Class<?> supportedType = input.supportedClass; return ClassUtils.isAssignable(supportedType, clazz) || ClassUtils.determineCommonAncestor(clazz, supportedType) != null; } }); if (match.isPresent()) { final OidCreatorKey key = match.get(); return this.oidCreatorsMap.get(key); } return null; }
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.// w w w . ja v a 2 s . co m * <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
/** * Introspect the factory method signatures on the given bean class, * trying to find a common {@code FactoryBean} object type declared there. * @param beanClass the bean class to find the factory method on * @param factoryMethodName the name of the factory method * @return the common {@code FactoryBean} object type, or {@code null} if none *//*from w ww .j a v a2 s .c om*/ @Nullable private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, final String factoryMethodName) { /** * Holder used to keep a reference to a {@code Class} value. */ class Holder { @Nullable Class<?> value = null; } final Holder objectType = new Holder(); // CGLIB subclass methods hide generic parameters; look at the original user class. Class<?> fbClass = ClassUtils.getUserClass(beanClass); // Find the given factory method, taking into account that in the case of // @Bean methods, there may be parameters present. ReflectionUtils.doWithMethods(fbClass, method -> { if (method.getName().equals(factoryMethodName) && FactoryBean.class.isAssignableFrom(method.getReturnType())) { Class<?> currentType = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class); if (currentType != null) { objectType.value = ClassUtils.determineCommonAncestor(currentType, objectType.value); } } }); return (objectType.value != null && Object.class != objectType.value ? objectType.value : null); }