@@ -706,96 +706,100 @@ protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition m
706
706
return cachedReturnType .resolve ();
707
707
}
708
708
709
- Class <?> factoryClass ;
710
- boolean isStatic = true ;
709
+ Class <?> commonType = null ;
710
+ Method uniqueCandidate = mbd . factoryMethodToIntrospect ;
711
711
712
- String factoryBeanName = mbd .getFactoryBeanName ();
713
- if (factoryBeanName != null ) {
714
- if (factoryBeanName .equals (beanName )) {
715
- throw new BeanDefinitionStoreException (mbd .getResourceDescription (), beanName ,
716
- "factory-bean reference points back to the same bean definition" );
717
- }
718
- // Check declared factory method return type on factory class.
719
- factoryClass = getType (factoryBeanName );
720
- isStatic = false ;
721
- }
722
- else {
723
- // Check declared factory method return type on bean class.
724
- factoryClass = resolveBeanClass (mbd , beanName , typesToMatch );
725
- }
712
+ if (uniqueCandidate == null ) {
713
+ Class <?> factoryClass ;
714
+ boolean isStatic = true ;
726
715
727
- if (factoryClass == null ) {
728
- return null ;
729
- }
730
- factoryClass = ClassUtils .getUserClass (factoryClass );
716
+ String factoryBeanName = mbd .getFactoryBeanName ();
717
+ if (factoryBeanName != null ) {
718
+ if (factoryBeanName .equals (beanName )) {
719
+ throw new BeanDefinitionStoreException (mbd .getResourceDescription (), beanName ,
720
+ "factory-bean reference points back to the same bean definition" );
721
+ }
722
+ // Check declared factory method return type on factory class.
723
+ factoryClass = getType (factoryBeanName );
724
+ isStatic = false ;
725
+ }
726
+ else {
727
+ // Check declared factory method return type on bean class.
728
+ factoryClass = resolveBeanClass (mbd , beanName , typesToMatch );
729
+ }
731
730
732
- // If all factory methods have the same return type, return that type.
733
- // Can't clearly figure out exact method due to type converting / autowiring!
734
- Class <?> commonType = null ;
735
- Method uniqueCandidate = null ;
736
- int minNrOfArgs =
737
- (mbd .hasConstructorArgumentValues () ? mbd .getConstructorArgumentValues ().getArgumentCount () : 0 );
738
- Method [] candidates = this .factoryMethodCandidateCache .computeIfAbsent (
739
- factoryClass , ReflectionUtils ::getUniqueDeclaredMethods );
740
-
741
- for (Method candidate : candidates ) {
742
- if (Modifier .isStatic (candidate .getModifiers ()) == isStatic && mbd .isFactoryMethod (candidate ) &&
743
- candidate .getParameterCount () >= minNrOfArgs ) {
744
- // Declared type variables to inspect?
745
- if (candidate .getTypeParameters ().length > 0 ) {
746
- try {
747
- // Fully resolve parameter names and argument values.
748
- Class <?>[] paramTypes = candidate .getParameterTypes ();
749
- String [] paramNames = null ;
750
- ParameterNameDiscoverer pnd = getParameterNameDiscoverer ();
751
- if (pnd != null ) {
752
- paramNames = pnd .getParameterNames (candidate );
753
- }
754
- ConstructorArgumentValues cav = mbd .getConstructorArgumentValues ();
755
- Set <ConstructorArgumentValues .ValueHolder > usedValueHolders = new HashSet <>(paramTypes .length );
756
- Object [] args = new Object [paramTypes .length ];
757
- for (int i = 0 ; i < args .length ; i ++) {
758
- ConstructorArgumentValues .ValueHolder valueHolder = cav .getArgumentValue (
759
- i , paramTypes [i ], (paramNames != null ? paramNames [i ] : null ), usedValueHolders );
760
- if (valueHolder == null ) {
761
- valueHolder = cav .getGenericArgumentValue (null , null , usedValueHolders );
731
+ if (factoryClass == null ) {
732
+ return null ;
733
+ }
734
+ factoryClass = ClassUtils .getUserClass (factoryClass );
735
+
736
+ // If all factory methods have the same return type, return that type.
737
+ // Can't clearly figure out exact method due to type converting / autowiring!
738
+ int minNrOfArgs =
739
+ (mbd .hasConstructorArgumentValues () ? mbd .getConstructorArgumentValues ().getArgumentCount () : 0 );
740
+ Method [] candidates = this .factoryMethodCandidateCache .computeIfAbsent (factoryClass ,
741
+ clazz -> ReflectionUtils .getUniqueDeclaredMethods (clazz , ReflectionUtils .USER_DECLARED_METHODS ));
742
+
743
+ for (Method candidate : candidates ) {
744
+ if (Modifier .isStatic (candidate .getModifiers ()) == isStatic && mbd .isFactoryMethod (candidate ) &&
745
+ candidate .getParameterCount () >= minNrOfArgs ) {
746
+ // Declared type variables to inspect?
747
+ if (candidate .getTypeParameters ().length > 0 ) {
748
+ try {
749
+ // Fully resolve parameter names and argument values.
750
+ Class <?>[] paramTypes = candidate .getParameterTypes ();
751
+ String [] paramNames = null ;
752
+ ParameterNameDiscoverer pnd = getParameterNameDiscoverer ();
753
+ if (pnd != null ) {
754
+ paramNames = pnd .getParameterNames (candidate );
755
+ }
756
+ ConstructorArgumentValues cav = mbd .getConstructorArgumentValues ();
757
+ Set <ConstructorArgumentValues .ValueHolder > usedValueHolders = new HashSet <>(paramTypes .length );
758
+ Object [] args = new Object [paramTypes .length ];
759
+ for (int i = 0 ; i < args .length ; i ++) {
760
+ ConstructorArgumentValues .ValueHolder valueHolder = cav .getArgumentValue (
761
+ i , paramTypes [i ], (paramNames != null ? paramNames [i ] : null ), usedValueHolders );
762
+ if (valueHolder == null ) {
763
+ valueHolder = cav .getGenericArgumentValue (null , null , usedValueHolders );
764
+ }
765
+ if (valueHolder != null ) {
766
+ args [i ] = valueHolder .getValue ();
767
+ usedValueHolders .add (valueHolder );
768
+ }
762
769
}
763
- if (valueHolder != null ) {
764
- args [i ] = valueHolder .getValue ();
765
- usedValueHolders .add (valueHolder );
770
+ Class <?> returnType = AutowireUtils .resolveReturnTypeForFactoryMethod (
771
+ candidate , args , getBeanClassLoader ());
772
+ uniqueCandidate = (commonType == null && returnType == candidate .getReturnType () ?
773
+ candidate : null );
774
+ commonType = ClassUtils .determineCommonAncestor (returnType , commonType );
775
+ if (commonType == null ) {
776
+ // Ambiguous return types found: return null to indicate "not determinable".
777
+ return null ;
778
+ }
779
+ }
780
+ catch (Throwable ex ) {
781
+ if (logger .isDebugEnabled ()) {
782
+ logger .debug ("Failed to resolve generic return type for factory method: " + ex );
766
783
}
767
784
}
768
- Class <?> returnType = AutowireUtils .resolveReturnTypeForFactoryMethod (
769
- candidate , args , getBeanClassLoader ());
770
- uniqueCandidate = (commonType == null && returnType == candidate .getReturnType () ?
771
- candidate : null );
772
- commonType = ClassUtils .determineCommonAncestor (returnType , commonType );
785
+ }
786
+ else {
787
+ uniqueCandidate = (commonType == null ? candidate : null );
788
+ commonType = ClassUtils .determineCommonAncestor (candidate .getReturnType (), commonType );
773
789
if (commonType == null ) {
774
790
// Ambiguous return types found: return null to indicate "not determinable".
775
791
return null ;
776
792
}
777
793
}
778
- catch (Throwable ex ) {
779
- if (logger .isDebugEnabled ()) {
780
- logger .debug ("Failed to resolve generic return type for factory method: " + ex );
781
- }
782
- }
783
- }
784
- else {
785
- uniqueCandidate = (commonType == null ? candidate : null );
786
- commonType = ClassUtils .determineCommonAncestor (candidate .getReturnType (), commonType );
787
- if (commonType == null ) {
788
- // Ambiguous return types found: return null to indicate "not determinable".
789
- return null ;
790
- }
791
794
}
792
795
}
793
- }
794
796
795
- mbd .factoryMethodToIntrospect = uniqueCandidate ;
796
- if (commonType == null ) {
797
- return null ;
797
+ mbd .factoryMethodToIntrospect = uniqueCandidate ;
798
+ if (commonType == null ) {
799
+ return null ;
800
+ }
798
801
}
802
+
799
803
// Common return type found: all factory methods return same type. For a non-parameterized
800
804
// unique candidate, cache the full type declaration context of the target factory method.
801
805
cachedReturnType = (uniqueCandidate != null ?
@@ -926,7 +930,7 @@ class Holder {
926
930
objectType .value = ClassUtils .determineCommonAncestor (currentType , objectType .value );
927
931
}
928
932
}
929
- });
933
+ }, ReflectionUtils . USER_DECLARED_METHODS );
930
934
931
935
return (objectType .value != null && Object .class != objectType .value ? objectType .value : null );
932
936
}
0 commit comments