1
1
/*
2
- * Copyright 2002-2013 the original author or authors.
2
+ * Copyright 2002-2014 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.
54
54
import org .springframework .util .StringUtils ;
55
55
56
56
/**
57
- * Helper class for resolving constructors and factory methods.
57
+ * Delegate for resolving constructors and factory methods.
58
58
* Performs constructor resolution through argument matching.
59
59
*
60
- * <p>Operates on an {@link AbstractBeanFactory} and an {@link InstantiationStrategy}.
61
- * Used by {@link AbstractAutowireCapableBeanFactory}.
62
- *
63
60
* @author Juergen Hoeller
64
61
* @author Rob Harrop
65
62
* @author Mark Fisher
@@ -103,12 +100,12 @@ public ConstructorResolver(AbstractAutowireCapableBeanFactory beanFactory) {
103
100
* @return a BeanWrapper for the new instance
104
101
*/
105
102
public BeanWrapper autowireConstructor (
106
- final String beanName , final RootBeanDefinition mbd , Constructor [] chosenCtors , final Object [] explicitArgs ) {
103
+ final String beanName , final RootBeanDefinition mbd , Constructor <?> [] chosenCtors , final Object [] explicitArgs ) {
107
104
108
105
BeanWrapperImpl bw = new BeanWrapperImpl ();
109
106
this .beanFactory .initBeanWrapper (bw );
110
107
111
- Constructor constructorToUse = null ;
108
+ Constructor <?> constructorToUse = null ;
112
109
ArgumentsHolder argsHolderToUse = null ;
113
110
Object [] argsToUse = null ;
114
111
@@ -118,7 +115,7 @@ public BeanWrapper autowireConstructor(
118
115
else {
119
116
Object [] argsToResolve = null ;
120
117
synchronized (mbd .constructorArgumentLock ) {
121
- constructorToUse = (Constructor ) mbd .resolvedConstructorOrFactoryMethod ;
118
+ constructorToUse = (Constructor <?> ) mbd .resolvedConstructorOrFactoryMethod ;
122
119
if (constructorToUse != null && mbd .constructorArgumentsResolved ) {
123
120
// Found a cached constructor...
124
121
argsToUse = mbd .resolvedConstructorArguments ;
@@ -149,7 +146,7 @@ public BeanWrapper autowireConstructor(
149
146
}
150
147
151
148
// Take specified constructors, if any.
152
- Constructor [] candidates = chosenCtors ;
149
+ Constructor <?> [] candidates = chosenCtors ;
153
150
if (candidates == null ) {
154
151
Class <?> beanClass = mbd .getBeanClass ();
155
152
try {
@@ -164,7 +161,7 @@ public BeanWrapper autowireConstructor(
164
161
}
165
162
AutowireUtils .sortConstructors (candidates );
166
163
int minTypeDiffWeight = Integer .MAX_VALUE ;
167
- Set <Constructor > ambiguousConstructors = null ;
164
+ Set <Constructor <?> > ambiguousConstructors = null ;
168
165
List <Exception > causes = null ;
169
166
170
167
for (int i = 0 ; i < candidates .length ; i ++) {
@@ -185,7 +182,7 @@ public BeanWrapper autowireConstructor(
185
182
try {
186
183
String [] paramNames = null ;
187
184
if (constructorPropertiesAnnotationAvailable ) {
188
- paramNames = ConstructorPropertiesChecker .evaluateAnnotation (candidate , paramTypes .length );
185
+ paramNames = ConstructorPropertiesChecker .evaluate (candidate , paramTypes .length );
189
186
}
190
187
if (paramNames == null ) {
191
188
ParameterNameDiscoverer pnd = this .beanFactory .getParameterNameDiscoverer ();
@@ -239,7 +236,7 @@ public BeanWrapper autowireConstructor(
239
236
}
240
237
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight ) {
241
238
if (ambiguousConstructors == null ) {
242
- ambiguousConstructors = new LinkedHashSet <Constructor >();
239
+ ambiguousConstructors = new LinkedHashSet <Constructor <?> >();
243
240
ambiguousConstructors .add (constructorToUse );
244
241
}
245
242
ambiguousConstructors .add (candidate );
@@ -267,7 +264,7 @@ else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution())
267
264
Object beanInstance ;
268
265
269
266
if (System .getSecurityManager () != null ) {
270
- final Constructor ctorToUse = constructorToUse ;
267
+ final Constructor <?> ctorToUse = constructorToUse ;
271
268
final Object [] argumentsToUse = argsToUse ;
272
269
beanInstance = AccessController .doPrivileged (new PrivilegedAction <Object >() {
273
270
public Object run () {
@@ -295,18 +292,22 @@ public Object run() {
295
292
* @param mbd the bean definition to check
296
293
*/
297
294
public void resolveFactoryMethodIfPossible (RootBeanDefinition mbd ) {
298
- Class factoryClass ;
295
+ Class <?> factoryClass ;
296
+ boolean isStatic ;
299
297
if (mbd .getFactoryBeanName () != null ) {
300
298
factoryClass = this .beanFactory .getType (mbd .getFactoryBeanName ());
299
+ isStatic = false ;
301
300
}
302
301
else {
303
302
factoryClass = mbd .getBeanClass ();
303
+ isStatic = true ;
304
304
}
305
305
factoryClass = ClassUtils .getUserClass (factoryClass );
306
- Method [] candidates = ReflectionUtils .getAllDeclaredMethods (factoryClass );
306
+
307
+ Method [] candidates = getCandidateMethods (factoryClass , mbd );
307
308
Method uniqueCandidate = null ;
308
309
for (Method candidate : candidates ) {
309
- if (mbd .isFactoryMethod (candidate )) {
310
+ if (Modifier . isStatic ( candidate . getModifiers ()) == isStatic && mbd .isFactoryMethod (candidate )) {
310
311
if (uniqueCandidate == null ) {
311
312
uniqueCandidate = candidate ;
312
313
}
@@ -321,6 +322,27 @@ else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParame
321
322
}
322
323
}
323
324
325
+ /**
326
+ * Retrieve all candidate methods for the given class, considering
327
+ * the {@link RootBeanDefinition#isNonPublicAccessAllowed()} flag.
328
+ * Called as the starting point for factory method determination.
329
+ */
330
+ private Method [] getCandidateMethods (final Class <?> factoryClass , final RootBeanDefinition mbd ) {
331
+ if (System .getSecurityManager () != null ) {
332
+ return AccessController .doPrivileged (new PrivilegedAction <Method []>() {
333
+ @ Override
334
+ public Method [] run () {
335
+ return (mbd .isNonPublicAccessAllowed () ?
336
+ ReflectionUtils .getAllDeclaredMethods (factoryClass ) : factoryClass .getMethods ());
337
+ }
338
+ });
339
+ }
340
+ else {
341
+ return (mbd .isNonPublicAccessAllowed () ?
342
+ ReflectionUtils .getAllDeclaredMethods (factoryClass ) : factoryClass .getMethods ());
343
+ }
344
+ }
345
+
324
346
/**
325
347
* Instantiate the bean using a named factory method. The method may be static, if the
326
348
* bean definition parameter specifies a class, rather than a "factory-bean", or
@@ -336,7 +358,9 @@ else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParame
336
358
* method, or {@code null} if none (-> use constructor argument values from bean definition)
337
359
* @return a BeanWrapper for the new instance
338
360
*/
339
- public BeanWrapper instantiateUsingFactoryMethod (final String beanName , final RootBeanDefinition mbd , final Object [] explicitArgs ) {
361
+ public BeanWrapper instantiateUsingFactoryMethod (
362
+ final String beanName , final RootBeanDefinition mbd , final Object [] explicitArgs ) {
363
+
340
364
BeanWrapperImpl bw = new BeanWrapperImpl ();
341
365
this .beanFactory .initBeanWrapper (bw );
342
366
@@ -397,27 +421,11 @@ public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final Ro
397
421
// Need to determine the factory method...
398
422
// Try all methods with this name to see if they match the given arguments.
399
423
factoryClass = ClassUtils .getUserClass (factoryClass );
400
- Method [] rawCandidates ;
401
-
402
- final Class <?> factoryClazz = factoryClass ;
403
- if (System .getSecurityManager () != null ) {
404
- rawCandidates = AccessController .doPrivileged (new PrivilegedAction <Method []>() {
405
- public Method [] run () {
406
- return (mbd .isNonPublicAccessAllowed () ?
407
- ReflectionUtils .getAllDeclaredMethods (factoryClazz ) : factoryClazz .getMethods ());
408
- }
409
- });
410
- }
411
- else {
412
- rawCandidates = (mbd .isNonPublicAccessAllowed () ?
413
- ReflectionUtils .getAllDeclaredMethods (factoryClazz ) : factoryClazz .getMethods ());
414
- }
415
424
425
+ Method [] rawCandidates = getCandidateMethods (factoryClass , mbd );
416
426
List <Method > candidateSet = new ArrayList <Method >();
417
427
for (Method candidate : rawCandidates ) {
418
- if (Modifier .isStatic (candidate .getModifiers ()) == isStatic &&
419
- candidate .getName ().equals (mbd .getFactoryMethodName ()) &&
420
- mbd .isFactoryMethod (candidate )) {
428
+ if (Modifier .isStatic (candidate .getModifiers ()) == isStatic && mbd .isFactoryMethod (candidate )) {
421
429
candidateSet .add (candidate );
422
430
}
423
431
}
@@ -759,7 +767,7 @@ private Object[] resolvePreparedArguments(
759
767
String beanName , RootBeanDefinition mbd , BeanWrapper bw , Member methodOrCtor , Object [] argsToResolve ) {
760
768
761
769
Class <?>[] paramTypes = (methodOrCtor instanceof Method ?
762
- ((Method ) methodOrCtor ).getParameterTypes () : ((Constructor ) methodOrCtor ).getParameterTypes ());
770
+ ((Method ) methodOrCtor ).getParameterTypes () : ((Constructor <?> ) methodOrCtor ).getParameterTypes ());
763
771
TypeConverter converter = (this .beanFactory .getCustomTypeConverter () != null ?
764
772
this .beanFactory .getCustomTypeConverter () : bw );
765
773
BeanDefinitionValueResolver valueResolver =
@@ -881,7 +889,7 @@ private static class AutowiredArgumentMarker {
881
889
*/
882
890
private static class ConstructorPropertiesChecker {
883
891
884
- public static String [] evaluateAnnotation (Constructor <?> candidate , int paramCount ) {
892
+ public static String [] evaluate (Constructor <?> candidate , int paramCount ) {
885
893
ConstructorProperties cp = candidate .getAnnotation (ConstructorProperties .class );
886
894
if (cp != null ) {
887
895
String [] names = cp .value ();
0 commit comments