11/*
2- * Copyright 2002-2015 the original author or authors.
2+ * Copyright 2002-2016 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
4545import javax .inject .Provider ;
4646
4747import org .springframework .beans .BeansException ;
48- import org .springframework .beans .FatalBeanException ;
4948import org .springframework .beans .TypeConverter ;
5049import org .springframework .beans .factory .BeanCreationException ;
5150import org .springframework .beans .factory .BeanCurrentlyInCreationException ;
113112public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
114113 implements ConfigurableListableBeanFactory , BeanDefinitionRegistry , Serializable {
115114
115+ private static final Object NOT_MULTIPLE_BEANS = new Object ();
116+
117+
116118 private static Class <?> javaUtilOptionalClass = null ;
117119
118120 private static Class <?> javaxInjectProviderClass = null ;
@@ -615,10 +617,12 @@ public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> a
615617
616618 @ Override
617619 public void registerResolvableDependency (Class <?> dependencyType , Object autowiredValue ) {
618- Assert .notNull (dependencyType , "Type must not be null" );
620+ Assert .notNull (dependencyType , "Dependency type must not be null" );
619621 if (autowiredValue != null ) {
620- Assert .isTrue ((autowiredValue instanceof ObjectFactory || dependencyType .isInstance (autowiredValue )),
621- "Value [" + autowiredValue + "] does not implement specified type [" + dependencyType .getName () + "]" );
622+ if (!(autowiredValue instanceof ObjectFactory || dependencyType .isInstance (autowiredValue ))) {
623+ throw new IllegalArgumentException ("Value [" + autowiredValue +
624+ "] does not implement specified dependency type [" + dependencyType .getName () + "]" );
625+ }
622626 this .resolvableDependencies .put (dependencyType , autowiredValue );
623627 }
624628 }
@@ -1034,15 +1038,54 @@ public Object doResolveDependency(DependencyDescriptor descriptor, String beanNa
10341038 converter .convertIfNecessary (value , type , descriptor .getMethodParameter ()));
10351039 }
10361040
1041+ Object multipleBeans = resolveMultipleBeans (descriptor , beanName , autowiredBeanNames , typeConverter );
1042+ if (multipleBeans != null && multipleBeans != NOT_MULTIPLE_BEANS ) {
1043+ return multipleBeans ;
1044+ }
1045+
1046+ Map <String , Object > matchingBeans = findAutowireCandidates (beanName , type , descriptor );
1047+ if (matchingBeans .isEmpty ()) {
1048+ if (descriptor .isRequired ()) {
1049+ raiseNoSuchBeanDefinitionException (type , descriptor .getResolvableType ().toString (), descriptor );
1050+ }
1051+ return null ;
1052+ }
1053+ if (matchingBeans .size () > 1 ) {
1054+ String primaryBeanName = determineAutowireCandidate (matchingBeans , descriptor );
1055+ if (primaryBeanName == null ) {
1056+ if (multipleBeans == NOT_MULTIPLE_BEANS || descriptor .isRequired ()) {
1057+ throw new NoUniqueBeanDefinitionException (type , matchingBeans .keySet ());
1058+ }
1059+ else {
1060+ // In case of an optional Collection/Map, silently ignore a non-unique case:
1061+ // possibly it was meant to be an empty collection of multiple regular beans
1062+ // (before 4.3 in particular when we didn't even look for collection beans).
1063+ return null ;
1064+ }
1065+ }
1066+ if (autowiredBeanNames != null ) {
1067+ autowiredBeanNames .add (primaryBeanName );
1068+ }
1069+ return matchingBeans .get (primaryBeanName );
1070+ }
1071+ // We have exactly one match.
1072+ Map .Entry <String , Object > entry = matchingBeans .entrySet ().iterator ().next ();
1073+ if (autowiredBeanNames != null ) {
1074+ autowiredBeanNames .add (entry .getKey ());
1075+ }
1076+ return entry .getValue ();
1077+ }
1078+
1079+ private Object resolveMultipleBeans (DependencyDescriptor descriptor , String beanName ,
1080+ Set <String > autowiredBeanNames , TypeConverter typeConverter ) {
1081+
1082+ Class <?> type = descriptor .getDependencyType ();
10371083 if (type .isArray ()) {
10381084 Class <?> componentType = type .getComponentType ();
10391085 DependencyDescriptor targetDesc = new DependencyDescriptor (descriptor );
10401086 targetDesc .increaseNestingLevel ();
10411087 Map <String , Object > matchingBeans = findAutowireCandidates (beanName , componentType , targetDesc );
10421088 if (matchingBeans .isEmpty ()) {
1043- if (descriptor .isRequired ()) {
1044- raiseNoSuchBeanDefinitionException (componentType , "array of " + componentType .getName (), descriptor );
1045- }
10461089 return null ;
10471090 }
10481091 if (autowiredBeanNames != null ) {
@@ -1058,18 +1101,12 @@ public Object doResolveDependency(DependencyDescriptor descriptor, String beanNa
10581101 else if (Collection .class .isAssignableFrom (type ) && type .isInterface ()) {
10591102 Class <?> elementType = descriptor .getCollectionType ();
10601103 if (elementType == null ) {
1061- if (descriptor .isRequired ()) {
1062- throw new FatalBeanException ("No element type declared for collection [" + type .getName () + "]" );
1063- }
10641104 return null ;
10651105 }
10661106 DependencyDescriptor targetDesc = new DependencyDescriptor (descriptor );
10671107 targetDesc .increaseNestingLevel ();
10681108 Map <String , Object > matchingBeans = findAutowireCandidates (beanName , elementType , targetDesc );
10691109 if (matchingBeans .isEmpty ()) {
1070- if (descriptor .isRequired ()) {
1071- raiseNoSuchBeanDefinitionException (elementType , "collection of " + elementType .getName (), descriptor );
1072- }
10731110 return null ;
10741111 }
10751112 if (autowiredBeanNames != null ) {
@@ -1085,26 +1122,16 @@ else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
10851122 else if (Map .class .isAssignableFrom (type ) && type .isInterface ()) {
10861123 Class <?> keyType = descriptor .getMapKeyType ();
10871124 if (String .class != keyType ) {
1088- if (descriptor .isRequired ()) {
1089- throw new FatalBeanException ("Key type [" + keyType + "] of map [" + type .getName () +
1090- "] must be [java.lang.String]" );
1091- }
10921125 return null ;
10931126 }
10941127 Class <?> valueType = descriptor .getMapValueType ();
10951128 if (valueType == null ) {
1096- if (descriptor .isRequired ()) {
1097- throw new FatalBeanException ("No value type declared for map [" + type .getName () + "]" );
1098- }
10991129 return null ;
11001130 }
11011131 DependencyDescriptor targetDesc = new DependencyDescriptor (descriptor );
11021132 targetDesc .increaseNestingLevel ();
11031133 Map <String , Object > matchingBeans = findAutowireCandidates (beanName , valueType , targetDesc );
11041134 if (matchingBeans .isEmpty ()) {
1105- if (descriptor .isRequired ()) {
1106- raiseNoSuchBeanDefinitionException (valueType , "map with value type " + valueType .getName (), descriptor );
1107- }
11081135 return null ;
11091136 }
11101137 if (autowiredBeanNames != null ) {
@@ -1113,29 +1140,7 @@ else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
11131140 return matchingBeans ;
11141141 }
11151142 else {
1116- Map <String , Object > matchingBeans = findAutowireCandidates (beanName , type , descriptor );
1117- if (matchingBeans .isEmpty ()) {
1118- if (descriptor .isRequired ()) {
1119- raiseNoSuchBeanDefinitionException (type , "" , descriptor );
1120- }
1121- return null ;
1122- }
1123- if (matchingBeans .size () > 1 ) {
1124- String primaryBeanName = determineAutowireCandidate (matchingBeans , descriptor );
1125- if (primaryBeanName == null ) {
1126- throw new NoUniqueBeanDefinitionException (type , matchingBeans .keySet ());
1127- }
1128- if (autowiredBeanNames != null ) {
1129- autowiredBeanNames .add (primaryBeanName );
1130- }
1131- return matchingBeans .get (primaryBeanName );
1132- }
1133- // We have exactly one match.
1134- Map .Entry <String , Object > entry = matchingBeans .entrySet ().iterator ().next ();
1135- if (autowiredBeanNames != null ) {
1136- autowiredBeanNames .add (entry .getKey ());
1137- }
1138- return entry .getValue ();
1143+ return NOT_MULTIPLE_BEANS ;
11391144 }
11401145 }
11411146
@@ -1193,12 +1198,21 @@ protected Map<String, Object> findAutowireCandidates(
11931198 }
11941199 }
11951200 if (result .isEmpty ()) {
1201+ // Consider fallback matches if the first pass failed to find anything...
11961202 DependencyDescriptor fallbackDescriptor = descriptor .forFallbackMatch ();
11971203 for (String candidateName : candidateNames ) {
1198- if (!candidateName . equals (beanName ) && isAutowireCandidate (candidateName , fallbackDescriptor )) {
1204+ if (!isSelfReference (beanName , candidateName ) && isAutowireCandidate (candidateName , fallbackDescriptor )) {
11991205 result .put (candidateName , getBean (candidateName ));
12001206 }
12011207 }
1208+ if (result .isEmpty ()) {
1209+ // Consider self references before as a final pass
1210+ for (String candidateName : candidateNames ) {
1211+ if (isSelfReference (beanName , candidateName ) && isAutowireCandidate (candidateName , fallbackDescriptor )) {
1212+ result .put (candidateName , getBean (candidateName ));
1213+ }
1214+ }
1215+ }
12021216 }
12031217 return result ;
12041218 }
0 commit comments