diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/BeanUtils.java b/org.springframework.beans/src/main/java/org/springframework/beans/BeanUtils.java index e13ae5fdbe..2e4bbc6c57 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -158,7 +158,7 @@ public abstract class BeanUtils { * @see java.lang.Class#getMethod * @see #findDeclaredMethod */ - public static Method findMethod(Class clazz, String methodName, Class[] paramTypes) { + public static Method findMethod(Class clazz, String methodName, Class... paramTypes) { try { return clazz.getMethod(methodName, paramTypes); } @@ -195,7 +195,7 @@ public abstract class BeanUtils { * declared on the given class or one of its superclasses. Prefers public methods, * but will return a protected, package access, or private method too. *
Checks This applies to constructor resolution, factory method resolution,
+ * and also init/destroy methods. Bean property accessors have to be public
+ * in any case and are not affected by this setting.
+ * Note that annotation-driven configuration will still access non-public
+ * members as far as they have been annotated. This setting applies to
+ * externalized metadata in this bean definition only.
+ */
+ public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) {
+ this.nonPublicAccessAllowed = nonPublicAccessAllowed;
+ }
+
+ /**
+ * Return whether to allow access to non-public constructors and methods.
+ */
+ public boolean isNonPublicAccessAllowed() {
+ return this.nonPublicAccessAllowed;
+ }
+
+ /**
+ * Specify whether to resolve constructors in lenient mode (Class.getMethods first, falling back to
- * findDeclaredMethodWithMinimalParameters. This allows to find public
+ * findDeclaredMethodWithMinimalParameters. This allows for finding public
* methods without issues even in environments with restricted Java security settings.
* @param clazz the class to check
* @param methodName the name of the method to find
@@ -208,7 +208,7 @@ public abstract class BeanUtils {
public static Method findMethodWithMinimalParameters(Class clazz, String methodName)
throws IllegalArgumentException {
- Method targetMethod = doFindMethodWithMinimalParameters(clazz.getDeclaredMethods(), methodName);
+ Method targetMethod = findMethodWithMinimalParameters(clazz.getMethods(), methodName);
if (targetMethod == null) {
targetMethod = findDeclaredMethodWithMinimalParameters(clazz, methodName);
}
@@ -230,7 +230,7 @@ public abstract class BeanUtils {
public static Method findDeclaredMethodWithMinimalParameters(Class clazz, String methodName)
throws IllegalArgumentException {
- Method targetMethod = doFindMethodWithMinimalParameters(clazz.getDeclaredMethods(), methodName);
+ Method targetMethod = findMethodWithMinimalParameters(clazz.getDeclaredMethods(), methodName);
if (targetMethod == null && clazz.getSuperclass() != null) {
targetMethod = findDeclaredMethodWithMinimalParameters(clazz.getSuperclass(), methodName);
}
@@ -246,7 +246,7 @@ public abstract class BeanUtils {
* @throws IllegalArgumentException if methods of the given name were found but
* could not be resolved to a unique method with minimal parameters
*/
- private static Method doFindMethodWithMinimalParameters(Method[] methods, String methodName)
+ public static Method findMethodWithMinimalParameters(Method[] methods, String methodName)
throws IllegalArgumentException {
Method targetMethod = null;
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
index c7e5f8b15d..947521f834 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
@@ -1388,10 +1388,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
((InitializingBean) bean).afterPropertiesSet();
}
- String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);
- if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
- !mbd.isExternallyManagedInitMethod(initMethodName)) {
- invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());
+ if (mbd != null) {
+ String initMethodName = mbd.getInitMethodName();
+ if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
+ !mbd.isExternallyManagedInitMethod(initMethodName)) {
+ invokeCustomInitMethod(beanName, bean, mbd);
+ }
}
}
@@ -1406,12 +1408,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param enforceInitMethod indicates whether the defined init method needs to exist
* @see #invokeInitMethods
*/
- protected void invokeCustomInitMethod(
- String beanName, Object bean, String initMethodName, boolean enforceInitMethod) throws Throwable {
-
- Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null);
+ protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable {
+ String initMethodName = mbd.getInitMethodName();
+ Method initMethod = (mbd.isNonPublicAccessAllowed() ?
+ BeanUtils.findMethod(bean.getClass(), initMethodName) :
+ ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
- if (enforceInitMethod) {
+ if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
index 0dc8f48709..9f28b41d17 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
@@ -141,10 +141,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
private final Maptrue,
+ * which is the default) or to switch to strict resolution (throwing an exception
+ * in case of ambigious constructors that all match when converting the arguments,
+ * whereas lenient mode would use the one with the 'closest' type matches).
+ */
+ public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
+ this.lenientConstructorResolution = lenientConstructorResolution;
+ }
+
+ /**
+ * Return whether to resolve constructors in lenient mode or in strict mode.
+ */
+ public boolean isLenientConstructorResolution() {
+ return this.lenientConstructorResolution;
+ }
+
/**
* Specify constructor argument values for this bean.
*/
@@ -672,23 +714,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
return !this.constructorArgumentValues.isEmpty();
}
- /**
- * Specify whether to resolve constructors in lenient mode (true,
- * which is the default) or to switch to strict resolution (throwing an exception
- * in case of ambigious constructors that all match when converting the arguments,
- * whereas lenient mode would use the one with the 'closest' type matches).
- */
- public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
- this.lenientConstructorResolution = lenientConstructorResolution;
- }
-
- /**
- * Return whether to resolve constructors in lenient mode or in strict mode.
- */
- public boolean isLenientConstructorResolution() {
- return this.lenientConstructorResolution;
- }
-
/**
* Specify property values for this bean, if any.
*/
@@ -976,6 +1001,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
if (!ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers)) return false;
if (this.primary != that.primary) return false;
+ if (this.nonPublicAccessAllowed != that.nonPublicAccessAllowed) return false;
+ if (this.lenientConstructorResolution != that.lenientConstructorResolution) return false;
if (!ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues)) return false;
if (!ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues)) return false;
if (!ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides)) return false;
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
index 6972e847b7..63462f3f47 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
@@ -142,7 +142,8 @@ class ConstructorResolver {
if (candidates == null) {
Class beanClass = mbd.getBeanClass();
try {
- candidates = beanClass.getDeclaredConstructors();
+ candidates = (mbd.isNonPublicAccessAllowed() ?
+ beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
@@ -354,7 +355,8 @@ 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 = ReflectionUtils.getAllDeclaredMethods(factoryClass);
+ Method[] rawCandidates = (mbd.isNonPublicAccessAllowed() ?
+ ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
Listnull)
- * @param beanName the name of the bean
- * @param invokeDisposableBean whether to actually invoke DisposableBean's destroy method here
- * @param destroyMethodName the name of the custom destroy method (null if there is none)
- * @param postProcessors the List of DestructionAwareBeanPostProcessors, if any
*/
private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean,
- String destroyMethodName, List