Skip to content

Commit 603cdea

Browse files
committed
resolveFactoryMethodIfPossible considers nonPublicAccessAllowed and SecurityManager
Issue: SPR-11422
1 parent 0ec99fd commit 603cdea

File tree

1 file changed

+35
-33
lines changed

1 file changed

+35
-33
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@
7171
*/
7272
class ConstructorResolver {
7373

74-
private static final String CONSTRUCTOR_PROPERTIES_CLASS_NAME = "java.beans.ConstructorProperties";
75-
76-
private static final boolean constructorPropertiesAnnotationAvailable =
77-
ClassUtils.isPresent(CONSTRUCTOR_PROPERTIES_CLASS_NAME, ConstructorResolver.class.getClassLoader());
78-
7974
private final AbstractAutowireCapableBeanFactory beanFactory;
8075

8176

@@ -183,10 +178,7 @@ public BeanWrapper autowireConstructor(
183178
ArgumentsHolder argsHolder;
184179
if (resolvedValues != null) {
185180
try {
186-
String[] paramNames = null;
187-
if (constructorPropertiesAnnotationAvailable) {
188-
paramNames = ConstructorPropertiesChecker.evaluateAnnotation(candidate, paramTypes.length);
189-
}
181+
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
190182
if (paramNames == null) {
191183
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
192184
if (pnd != null) {
@@ -297,17 +289,21 @@ public Object run() {
297289
*/
298290
public void resolveFactoryMethodIfPossible(RootBeanDefinition mbd) {
299291
Class<?> factoryClass;
292+
boolean isStatic;
300293
if (mbd.getFactoryBeanName() != null) {
301294
factoryClass = this.beanFactory.getType(mbd.getFactoryBeanName());
295+
isStatic = false;
302296
}
303297
else {
304298
factoryClass = mbd.getBeanClass();
299+
isStatic = true;
305300
}
306301
factoryClass = ClassUtils.getUserClass(factoryClass);
307-
Method[] candidates = ReflectionUtils.getAllDeclaredMethods(factoryClass);
302+
303+
Method[] candidates = getCandidateMethods(factoryClass, mbd);
308304
Method uniqueCandidate = null;
309305
for (Method candidate : candidates) {
310-
if (mbd.isFactoryMethod(candidate)) {
306+
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
311307
if (uniqueCandidate == null) {
312308
uniqueCandidate = candidate;
313309
}
@@ -322,6 +318,27 @@ else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParame
322318
}
323319
}
324320

321+
/**
322+
* Retrieve all candidate methods for the given class, considering
323+
* the {@link RootBeanDefinition#isNonPublicAccessAllowed()} flag.
324+
* Called as the starting point for factory method determination.
325+
*/
326+
private Method[] getCandidateMethods(final Class<?> factoryClass, final RootBeanDefinition mbd) {
327+
if (System.getSecurityManager() != null) {
328+
return AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
329+
@Override
330+
public Method[] run() {
331+
return (mbd.isNonPublicAccessAllowed() ?
332+
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
333+
}
334+
});
335+
}
336+
else {
337+
return (mbd.isNonPublicAccessAllowed() ?
338+
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
339+
}
340+
}
341+
325342
/**
326343
* Instantiate the bean using a named factory method. The method may be static, if the
327344
* bean definition parameter specifies a class, rather than a "factory-bean", or
@@ -337,7 +354,9 @@ else if (!Arrays.equals(uniqueCandidate.getParameterTypes(), candidate.getParame
337354
* method, or {@code null} if none (-> use constructor argument values from bean definition)
338355
* @return a BeanWrapper for the new instance
339356
*/
340-
public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {
357+
public BeanWrapper instantiateUsingFactoryMethod(
358+
final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {
359+
341360
BeanWrapperImpl bw = new BeanWrapperImpl();
342361
this.beanFactory.initBeanWrapper(bw);
343362

@@ -398,28 +417,11 @@ public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final Ro
398417
// Need to determine the factory method...
399418
// Try all methods with this name to see if they match the given arguments.
400419
factoryClass = ClassUtils.getUserClass(factoryClass);
401-
Method[] rawCandidates;
402-
403-
final Class<?> factoryClazz = factoryClass;
404-
if (System.getSecurityManager() != null) {
405-
rawCandidates = AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
406-
@Override
407-
public Method[] run() {
408-
return (mbd.isNonPublicAccessAllowed() ?
409-
ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods());
410-
}
411-
});
412-
}
413-
else {
414-
rawCandidates = (mbd.isNonPublicAccessAllowed() ?
415-
ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods());
416-
}
417420

421+
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
418422
List<Method> candidateSet = new ArrayList<Method>();
419423
for (Method candidate : rawCandidates) {
420-
if (Modifier.isStatic(candidate.getModifiers()) == isStatic &&
421-
candidate.getName().equals(mbd.getFactoryMethodName()) &&
422-
mbd.isFactoryMethod(candidate)) {
424+
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
423425
candidateSet.add(candidate);
424426
}
425427
}
@@ -880,11 +882,11 @@ private static class AutowiredArgumentMarker {
880882

881883

882884
/**
883-
* Inner class to avoid a Java 6 dependency.
885+
* Delegate for checking Java 6's {@link ConstructorProperties} annotation.
884886
*/
885887
private static class ConstructorPropertiesChecker {
886888

887-
public static String[] evaluateAnnotation(Constructor<?> candidate, int paramCount) {
889+
public static String[] evaluate(Constructor<?> candidate, int paramCount) {
888890
ConstructorProperties cp = candidate.getAnnotation(ConstructorProperties.class);
889891
if (cp != null) {
890892
String[] names = cp.value();

0 commit comments

Comments
 (0)