20
20
import java .lang .reflect .Executable ;
21
21
import java .lang .reflect .Method ;
22
22
import java .lang .reflect .Modifier ;
23
+ import java .lang .reflect .Parameter ;
23
24
import java .util .Arrays ;
25
+ import java .util .HashSet ;
24
26
import java .util .LinkedHashSet ;
27
+ import java .util .Map ;
25
28
import java .util .Set ;
26
29
import java .util .stream .Collectors ;
27
30
@@ -248,7 +251,7 @@ private AutowiredArguments resolveArguments(RegisteredBean registeredBean, Execu
248
251
Assert .isTrue (this .shortcuts == null || this .shortcuts .length == resolved .length ,
249
252
() -> "'shortcuts' must contain " + resolved .length + " elements" );
250
253
251
- ConstructorArgumentValues argumentValues = resolveArgumentValues (registeredBean );
254
+ ValueHolder [] argumentValues = resolveArgumentValues (registeredBean , executable );
252
255
Set <String > autowiredBeanNames = new LinkedHashSet <>(resolved .length * 2 );
253
256
for (int i = startIndex ; i < parameterCount ; i ++) {
254
257
MethodParameter parameter = getMethodParameter (executable , i );
@@ -257,8 +260,9 @@ private AutowiredArguments resolveArguments(RegisteredBean registeredBean, Execu
257
260
if (shortcut != null ) {
258
261
descriptor = new ShortcutDependencyDescriptor (descriptor , shortcut );
259
262
}
260
- ValueHolder argumentValue = argumentValues .getIndexedArgumentValue (i , null );
261
- resolved [i - startIndex ] = resolveArgument (registeredBean , descriptor , argumentValue , autowiredBeanNames );
263
+ ValueHolder argumentValue = argumentValues [i ];
264
+ resolved [i - startIndex ] = resolveAutowiredArgument (
265
+ registeredBean , descriptor , argumentValue , autowiredBeanNames );
262
266
}
263
267
registerDependentBeans (registeredBean .getBeanFactory (), registeredBean .getBeanName (), autowiredBeanNames );
264
268
@@ -275,22 +279,44 @@ private MethodParameter getMethodParameter(Executable executable, int index) {
275
279
throw new IllegalStateException ("Unsupported executable: " + executable .getClass ().getName ());
276
280
}
277
281
278
- private ConstructorArgumentValues resolveArgumentValues (RegisteredBean registeredBean ) {
279
- ConstructorArgumentValues resolved = new ConstructorArgumentValues ();
282
+ private ValueHolder [] resolveArgumentValues (RegisteredBean registeredBean , Executable executable ) {
283
+ Parameter [] parameters = executable .getParameters ();
284
+ ValueHolder [] resolved = new ValueHolder [parameters .length ];
280
285
RootBeanDefinition beanDefinition = registeredBean .getMergedBeanDefinition ();
281
286
if (beanDefinition .hasConstructorArgumentValues () &&
282
287
registeredBean .getBeanFactory () instanceof AbstractAutowireCapableBeanFactory beanFactory ) {
283
288
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver (
284
289
beanFactory , registeredBean .getBeanName (), beanDefinition , beanFactory .getTypeConverter ());
285
- ConstructorArgumentValues values = beanDefinition .getConstructorArgumentValues ();
286
- values .getIndexedArgumentValues ().forEach ((index , valueHolder ) -> {
287
- ValueHolder resolvedValue = resolveArgumentValue (valueResolver , valueHolder );
288
- resolved .addIndexedArgumentValue (index , resolvedValue );
289
- });
290
+ ConstructorArgumentValues values = resolveConstructorArguments (
291
+ valueResolver , beanDefinition .getConstructorArgumentValues ());
292
+ Set <ValueHolder > usedValueHolders = new HashSet <>(parameters .length );
293
+ for (int i = 0 ; i < parameters .length ; i ++) {
294
+ Class <?> parameterType = parameters [i ].getType ();
295
+ String parameterName = (parameters [i ].isNamePresent () ? parameters [i ].getName () : null );
296
+ ValueHolder valueHolder = values .getArgumentValue (
297
+ i , parameterType , parameterName , usedValueHolders );
298
+ if (valueHolder != null ) {
299
+ resolved [i ] = valueHolder ;
300
+ usedValueHolders .add (valueHolder );
301
+ }
302
+ }
290
303
}
291
304
return resolved ;
292
305
}
293
306
307
+ private ConstructorArgumentValues resolveConstructorArguments (
308
+ BeanDefinitionValueResolver valueResolver , ConstructorArgumentValues constructorArguments ) {
309
+
310
+ ConstructorArgumentValues resolvedConstructorArguments = new ConstructorArgumentValues ();
311
+ for (Map .Entry <Integer , ConstructorArgumentValues .ValueHolder > entry : constructorArguments .getIndexedArgumentValues ().entrySet ()) {
312
+ resolvedConstructorArguments .addIndexedArgumentValue (entry .getKey (), resolveArgumentValue (valueResolver , entry .getValue ()));
313
+ }
314
+ for (ConstructorArgumentValues .ValueHolder valueHolder : constructorArguments .getGenericArgumentValues ()) {
315
+ resolvedConstructorArguments .addGenericArgumentValue (resolveArgumentValue (valueResolver , valueHolder ));
316
+ }
317
+ return resolvedConstructorArguments ;
318
+ }
319
+
294
320
private ValueHolder resolveArgumentValue (BeanDefinitionValueResolver resolver , ValueHolder valueHolder ) {
295
321
if (valueHolder .isConverted ()) {
296
322
return valueHolder ;
@@ -302,7 +328,7 @@ private ValueHolder resolveArgumentValue(BeanDefinitionValueResolver resolver, V
302
328
}
303
329
304
330
@ Nullable
305
- private Object resolveArgument (RegisteredBean registeredBean , DependencyDescriptor descriptor ,
331
+ private Object resolveAutowiredArgument (RegisteredBean registeredBean , DependencyDescriptor descriptor ,
306
332
@ Nullable ValueHolder argumentValue , Set <String > autowiredBeanNames ) {
307
333
308
334
TypeConverter typeConverter = registeredBean .getBeanFactory ().getTypeConverter ();
0 commit comments