diff --git a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java index 76c295490e0..54467cd3ea8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java +++ b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java @@ -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: *
{@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 findNonVoidWriteMethods(MethodDescriptor[] methodDescriptors) {
+ private List findCandidateWriteMethods(MethodDescriptor[] methodDescriptors) {
List matches = new ArrayList();
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];
diff --git a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java
index 7e462119226..183ffe4e2a3 100644
--- a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java
+++ b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfoFactory.java
@@ -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;
}
}
diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java
index 7da97104176..9ea8c569e7e 100644
--- a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java
@@ -1550,6 +1550,24 @@ public final class BeanWrapperTests {
assertEquals(TestEnum.TEST_VALUE, consumer.getEnumValue());
}
+ @Test
+ public void cornerSpr10115() {
+ Spr10115Bean foo = new Spr10115Bean();
+ BeanWrapperImpl bwi = new BeanWrapperImpl();
+ bwi.setWrappedInstance(foo);
+ bwi.setPropertyValue("prop1", "val1");
+ assertEquals("val1", Spr10115Bean.prop1);
+ }
+
+
+ static class Spr10115Bean {
+ private static String prop1;
+
+ public static void setProp1(String prop1) {
+ Spr10115Bean.prop1 = prop1;
+ }
+ }
+
private static class Foo {
diff --git a/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java b/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java
index fd53b58af71..44062a9107b 100644
--- a/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/ExtendedBeanInfoTests.java
@@ -946,4 +946,28 @@ public class ExtendedBeanInfoTests {
assertThat(hasIndexedWriteMethodForProperty(bi, "address"), is(true));
}
}
+
+ @Test
+ public void shouldSupportStaticWriteMethod() throws IntrospectionException {
+ {
+ BeanInfo bi = Introspector.getBeanInfo(WithStaticWriteMethod.class);
+ assertThat(hasReadMethodForProperty(bi, "prop1"), is(false));
+ assertThat(hasWriteMethodForProperty(bi, "prop1"), is(false));
+ assertThat(hasIndexedReadMethodForProperty(bi, "prop1"), is(false));
+ assertThat(hasIndexedWriteMethodForProperty(bi, "prop1"), is(false));
+ }
+ {
+ BeanInfo bi = new ExtendedBeanInfo(Introspector.getBeanInfo(WithStaticWriteMethod.class));
+ assertThat(hasReadMethodForProperty(bi, "prop1"), is(false));
+ assertThat(hasWriteMethodForProperty(bi, "prop1"), is(true));
+ assertThat(hasIndexedReadMethodForProperty(bi, "prop1"), is(false));
+ assertThat(hasIndexedWriteMethodForProperty(bi, "prop1"), is(false));
+ }
+ }
+
+ static class WithStaticWriteMethod {
+ @SuppressWarnings("unused")
+ public static void setProp1(String prop1) {
+ }
+ }
}