1
1
/*
2
- * Copyright 2002-2015 the original author or authors.
2
+ * Copyright 2002-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
45
45
import javax .inject .Provider ;
46
46
47
47
import org .springframework .beans .BeansException ;
48
- import org .springframework .beans .FatalBeanException ;
49
48
import org .springframework .beans .TypeConverter ;
50
49
import org .springframework .beans .factory .BeanCreationException ;
51
50
import org .springframework .beans .factory .BeanCurrentlyInCreationException ;
113
112
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
114
113
implements ConfigurableListableBeanFactory , BeanDefinitionRegistry , Serializable {
115
114
115
+ private static final Object NOT_MULTIPLE_BEANS = new Object ();
116
+
117
+
116
118
private static Class <?> javaUtilOptionalClass = null ;
117
119
118
120
private static Class <?> javaxInjectProviderClass = null ;
@@ -615,10 +617,12 @@ public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> a
615
617
616
618
@ Override
617
619
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" );
619
621
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
+ }
622
626
this .resolvableDependencies .put (dependencyType , autowiredValue );
623
627
}
624
628
}
@@ -1034,15 +1038,54 @@ public Object doResolveDependency(DependencyDescriptor descriptor, String beanNa
1034
1038
converter .convertIfNecessary (value , type , descriptor .getMethodParameter ()));
1035
1039
}
1036
1040
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 ();
1037
1083
if (type .isArray ()) {
1038
1084
Class <?> componentType = type .getComponentType ();
1039
1085
DependencyDescriptor targetDesc = new DependencyDescriptor (descriptor );
1040
1086
targetDesc .increaseNestingLevel ();
1041
1087
Map <String , Object > matchingBeans = findAutowireCandidates (beanName , componentType , targetDesc );
1042
1088
if (matchingBeans .isEmpty ()) {
1043
- if (descriptor .isRequired ()) {
1044
- raiseNoSuchBeanDefinitionException (componentType , "array of " + componentType .getName (), descriptor );
1045
- }
1046
1089
return null ;
1047
1090
}
1048
1091
if (autowiredBeanNames != null ) {
@@ -1058,18 +1101,12 @@ public Object doResolveDependency(DependencyDescriptor descriptor, String beanNa
1058
1101
else if (Collection .class .isAssignableFrom (type ) && type .isInterface ()) {
1059
1102
Class <?> elementType = descriptor .getCollectionType ();
1060
1103
if (elementType == null ) {
1061
- if (descriptor .isRequired ()) {
1062
- throw new FatalBeanException ("No element type declared for collection [" + type .getName () + "]" );
1063
- }
1064
1104
return null ;
1065
1105
}
1066
1106
DependencyDescriptor targetDesc = new DependencyDescriptor (descriptor );
1067
1107
targetDesc .increaseNestingLevel ();
1068
1108
Map <String , Object > matchingBeans = findAutowireCandidates (beanName , elementType , targetDesc );
1069
1109
if (matchingBeans .isEmpty ()) {
1070
- if (descriptor .isRequired ()) {
1071
- raiseNoSuchBeanDefinitionException (elementType , "collection of " + elementType .getName (), descriptor );
1072
- }
1073
1110
return null ;
1074
1111
}
1075
1112
if (autowiredBeanNames != null ) {
@@ -1085,26 +1122,16 @@ else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
1085
1122
else if (Map .class .isAssignableFrom (type ) && type .isInterface ()) {
1086
1123
Class <?> keyType = descriptor .getMapKeyType ();
1087
1124
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
- }
1092
1125
return null ;
1093
1126
}
1094
1127
Class <?> valueType = descriptor .getMapValueType ();
1095
1128
if (valueType == null ) {
1096
- if (descriptor .isRequired ()) {
1097
- throw new FatalBeanException ("No value type declared for map [" + type .getName () + "]" );
1098
- }
1099
1129
return null ;
1100
1130
}
1101
1131
DependencyDescriptor targetDesc = new DependencyDescriptor (descriptor );
1102
1132
targetDesc .increaseNestingLevel ();
1103
1133
Map <String , Object > matchingBeans = findAutowireCandidates (beanName , valueType , targetDesc );
1104
1134
if (matchingBeans .isEmpty ()) {
1105
- if (descriptor .isRequired ()) {
1106
- raiseNoSuchBeanDefinitionException (valueType , "map with value type " + valueType .getName (), descriptor );
1107
- }
1108
1135
return null ;
1109
1136
}
1110
1137
if (autowiredBeanNames != null ) {
@@ -1113,29 +1140,7 @@ else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
1113
1140
return matchingBeans ;
1114
1141
}
1115
1142
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 ;
1139
1144
}
1140
1145
}
1141
1146
@@ -1193,12 +1198,21 @@ protected Map<String, Object> findAutowireCandidates(
1193
1198
}
1194
1199
}
1195
1200
if (result .isEmpty ()) {
1201
+ // Consider fallback matches if the first pass failed to find anything...
1196
1202
DependencyDescriptor fallbackDescriptor = descriptor .forFallbackMatch ();
1197
1203
for (String candidateName : candidateNames ) {
1198
- if (!candidateName . equals (beanName ) && isAutowireCandidate (candidateName , fallbackDescriptor )) {
1204
+ if (!isSelfReference (beanName , candidateName ) && isAutowireCandidate (candidateName , fallbackDescriptor )) {
1199
1205
result .put (candidateName , getBean (candidateName ));
1200
1206
}
1201
1207
}
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
+ }
1202
1216
}
1203
1217
return result ;
1204
1218
}
0 commit comments