From 603cdea26e0880a46c697194bf5f1cbe60177f16 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 12 Feb 2014 23:48:16 +0100 Subject: [PATCH] resolveFactoryMethodIfPossible considers nonPublicAccessAllowed and SecurityManager Issue: SPR-11422 --- .../factory/support/ConstructorResolver.java | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java index 617c4fd94a..1c7fe6303d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java @@ -71,11 +71,6 @@ import org.springframework.util.StringUtils; */ class ConstructorResolver { - private static final String CONSTRUCTOR_PROPERTIES_CLASS_NAME = "java.beans.ConstructorProperties"; - - private static final boolean constructorPropertiesAnnotationAvailable = - ClassUtils.isPresent(CONSTRUCTOR_PROPERTIES_CLASS_NAME, ConstructorResolver.class.getClassLoader()); - private final AbstractAutowireCapableBeanFactory beanFactory; @@ -183,10 +178,7 @@ class ConstructorResolver { ArgumentsHolder argsHolder; if (resolvedValues != null) { try { - String[] paramNames = null; - if (constructorPropertiesAnnotationAvailable) { - paramNames = ConstructorPropertiesChecker.evaluateAnnotation(candidate, paramTypes.length); - } + String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length); if (paramNames == null) { ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { @@ -297,17 +289,21 @@ class ConstructorResolver { */ public void resolveFactoryMethodIfPossible(RootBeanDefinition mbd) { Class factoryClass; + boolean isStatic; if (mbd.getFactoryBeanName() != null) { factoryClass = this.beanFactory.getType(mbd.getFactoryBeanName()); + isStatic = false; } else { factoryClass = mbd.getBeanClass(); + isStatic = true; } factoryClass = ClassUtils.getUserClass(factoryClass); - Method[] candidates = ReflectionUtils.getAllDeclaredMethods(factoryClass); + + Method[] candidates = getCandidateMethods(factoryClass, mbd); Method uniqueCandidate = null; for (Method candidate : candidates) { - if (mbd.isFactoryMethod(candidate)) { + if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) { if (uniqueCandidate == null) { uniqueCandidate = candidate; } @@ -322,6 +318,27 @@ class ConstructorResolver { } } + /** + * Retrieve all candidate methods for the given class, considering + * the {@link RootBeanDefinition#isNonPublicAccessAllowed()} flag. + * Called as the starting point for factory method determination. + */ + private Method[] getCandidateMethods(final Class factoryClass, final RootBeanDefinition mbd) { + if (System.getSecurityManager() != null) { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Method[] run() { + return (mbd.isNonPublicAccessAllowed() ? + ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()); + } + }); + } + else { + return (mbd.isNonPublicAccessAllowed() ? + ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()); + } + } + /** * Instantiate the bean using a named factory method. The method may be static, if the * bean definition parameter specifies a class, rather than a "factory-bean", or @@ -337,7 +354,9 @@ class ConstructorResolver { * method, or {@code null} if none (-> use constructor argument values from bean definition) * @return a BeanWrapper for the new instance */ - public BeanWrapper instantiateUsingFactoryMethod(final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) { + public BeanWrapper instantiateUsingFactoryMethod( + final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) { + BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); @@ -398,28 +417,11 @@ class ConstructorResolver { // Need to determine the factory method... // Try all methods with this name to see if they match the given arguments. factoryClass = ClassUtils.getUserClass(factoryClass); - Method[] rawCandidates; - - final Class factoryClazz = factoryClass; - if (System.getSecurityManager() != null) { - rawCandidates = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Method[] run() { - return (mbd.isNonPublicAccessAllowed() ? - ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods()); - } - }); - } - else { - rawCandidates = (mbd.isNonPublicAccessAllowed() ? - ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods()); - } + Method[] rawCandidates = getCandidateMethods(factoryClass, mbd); List candidateSet = new ArrayList(); for (Method candidate : rawCandidates) { - if (Modifier.isStatic(candidate.getModifiers()) == isStatic && - candidate.getName().equals(mbd.getFactoryMethodName()) && - mbd.isFactoryMethod(candidate)) { + if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) { candidateSet.add(candidate); } } @@ -880,11 +882,11 @@ class ConstructorResolver { /** - * Inner class to avoid a Java 6 dependency. + * Delegate for checking Java 6's {@link ConstructorProperties} annotation. */ private static class ConstructorPropertiesChecker { - public static String[] evaluateAnnotation(Constructor candidate, int paramCount) { + public static String[] evaluate(Constructor candidate, int paramCount) { ConstructorProperties cp = candidate.getAnnotation(ConstructorProperties.class); if (cp != null) { String[] names = cp.value();