Fix regression in static setter method support
The intention of ExtendedBeanInfo, introduced with SPR-8079 in v3.1.0.M2, was to support dependency injection against non-void returning write methods. However, it also inadvertently introduced support for injection against static setter methods. When use of ExtendedBeanInfo was made optional with SPR-9723 in v3.2.0.M2, ExtendedBeanInfo continued to support static write methods, but its new BeanInfoFactory-based approach to testing whether or not a given bean class contains candidate write methods was written in a fashion exclusive of static methods, and this thereby introduced a regression - a regression in an otherwise undocumented and unintended feature, but a regression nevertheless. The reporting of SPR-10115 proves that at least one user has come to depend on this behavior allowing injection against static write methods, and so this commit fixes the regression by ensuring that the candidacy test includes standard and non-void setter methods having a static modifier. Issue: SPR-10115, SPR-9723, SPR-8079
This commit is contained in:
@@ -41,8 +41,8 @@ import static org.springframework.beans.PropertyDescriptorUtils.*;
|
||||
|
||||
/**
|
||||
* Decorator for a standard {@link BeanInfo} object, e.g. as created by
|
||||
* {@link Introspector#getBeanInfo(Class)}, designed to discover and register non-void
|
||||
* returning setter methods. For example:
|
||||
* {@link Introspector#getBeanInfo(Class)}, designed to discover and register static
|
||||
* and/or non-void returning setter methods. For example:
|
||||
* <pre>{@code
|
||||
* public class Bean {
|
||||
* private Foo foo;
|
||||
@@ -102,37 +102,40 @@ class ExtendedBeanInfo implements BeanInfo {
|
||||
new SimpleNonIndexedPropertyDescriptor(pd));
|
||||
}
|
||||
|
||||
for (Method method : findNonVoidWriteMethods(delegate.getMethodDescriptors())) {
|
||||
handleNonVoidWriteMethod(method);
|
||||
for (Method method : findCandidateWriteMethods(delegate.getMethodDescriptors())) {
|
||||
handleCandidateWriteMethod(method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<Method> findNonVoidWriteMethods(MethodDescriptor[] methodDescriptors) {
|
||||
private List<Method> findCandidateWriteMethods(MethodDescriptor[] methodDescriptors) {
|
||||
List<Method> matches = new ArrayList<Method>();
|
||||
for (MethodDescriptor methodDescriptor : methodDescriptors) {
|
||||
Method method = methodDescriptor.getMethod();
|
||||
if (isNonVoidWriteMethod(method)) {
|
||||
if (isCandidateWriteMethod(method)) {
|
||||
matches.add(method);
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
public static boolean isNonVoidWriteMethod(Method method) {
|
||||
public static boolean isCandidateWriteMethod(Method method) {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
int nParams = parameterTypes.length;
|
||||
if (methodName.length() > 3 && methodName.startsWith("set") &&
|
||||
Modifier.isPublic(method.getModifiers()) &&
|
||||
!void.class.isAssignableFrom(method.getReturnType()) &&
|
||||
(
|
||||
!void.class.isAssignableFrom(method.getReturnType()) ||
|
||||
Modifier.isStatic(method.getModifiers())
|
||||
) &&
|
||||
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class)))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleNonVoidWriteMethod(Method method) throws IntrospectionException {
|
||||
private void handleCandidateWriteMethod(Method method) throws IntrospectionException {
|
||||
int nParams = method.getParameterTypes().length;
|
||||
String propertyName = propertyNameFor(method);
|
||||
Class<?> propertyType = method.getParameterTypes()[nParams-1];
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ExtendedBeanInfoFactory implements Ordered, BeanInfoFactory {
|
||||
*/
|
||||
private boolean supports(Class<?> beanClass) {
|
||||
for (Method method : beanClass.getMethods()) {
|
||||
if (ExtendedBeanInfo.isNonVoidWriteMethod(method)) {
|
||||
if (ExtendedBeanInfo.isCandidateWriteMethod(method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user