Skip to content

Commit cb44e09

Browse files
committed
Merge branch '5.3.x'
2 parents 6d688e1 + 8e25e32 commit cb44e09

File tree

4 files changed

+75
-27
lines changed

4 files changed

+75
-27
lines changed

Diff for: spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java

+41-24
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import java.beans.IntrospectionException;
2020
import java.beans.PropertyDescriptor;
2121
import java.lang.reflect.Method;
22+
import java.util.ArrayList;
2223
import java.util.Collection;
2324
import java.util.Enumeration;
25+
import java.util.List;
2426
import java.util.Map;
2527
import java.util.TreeMap;
2628

@@ -52,8 +54,10 @@ abstract class PropertyDescriptorUtils {
5254
* @see SimpleBeanInfoFactory
5355
* @see java.beans.Introspector#getBeanInfo(Class)
5456
*/
55-
public static Collection<PropertyDescriptor> determineBasicProperties(Class<?> beanClass) throws IntrospectionException {
56-
Map<String, PropertyDescriptor> pdMap = new TreeMap<>();
57+
public static Collection<? extends PropertyDescriptor> determineBasicProperties(Class<?> beanClass)
58+
throws IntrospectionException {
59+
60+
Map<String, BasicPropertyDescriptor> pdMap = new TreeMap<>();
5761

5862
for (Method method : beanClass.getMethods()) {
5963
String methodName = method.getName();
@@ -81,39 +85,26 @@ else if (methodName.startsWith("is") && method.getParameterCount() == 0 && metho
8185
continue;
8286
}
8387

84-
PropertyDescriptor pd = pdMap.get(propertyName);
88+
BasicPropertyDescriptor pd = pdMap.get(propertyName);
8589
if (pd != null) {
8690
if (setter) {
8791
if (pd.getWriteMethod() == null ||
8892
pd.getWriteMethod().getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
89-
try {
90-
pd.setWriteMethod(method);
91-
}
92-
catch (IntrospectionException ex) {
93-
// typically a type mismatch -> ignore
94-
}
93+
pd.setWriteMethod(method);
94+
}
95+
else {
96+
pd.addWriteMethod(method);
9597
}
9698
}
9799
else {
98100
if (pd.getReadMethod() == null ||
99101
(pd.getReadMethod().getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
100-
try {
101-
pd.setReadMethod(method);
102-
}
103-
catch (IntrospectionException ex) {
104-
// typically a type mismatch -> ignore
105-
}
102+
pd.setReadMethod(method);
106103
}
107104
}
108105
}
109106
else {
110-
pd = new BasicPropertyDescriptor(propertyName, beanClass);
111-
if (setter) {
112-
pd.setWriteMethod(method);
113-
}
114-
else {
115-
pd.setReadMethod(method);
116-
}
107+
pd = new BasicPropertyDescriptor(propertyName, (!setter ? method : null), (setter ? method : null));
117108
pdMap.put(propertyName, pd);
118109
}
119110
}
@@ -277,8 +268,12 @@ private static class BasicPropertyDescriptor extends PropertyDescriptor {
277268
@Nullable
278269
private Method writeMethod;
279270

280-
public BasicPropertyDescriptor(String propertyName, Class<?> beanClass) throws IntrospectionException {
281-
super(propertyName, beanClass, null, null);
271+
private final List<Method> alternativeWriteMethods = new ArrayList<>();
272+
273+
public BasicPropertyDescriptor(String propertyName, @Nullable Method readMethod, @Nullable Method writeMethod)
274+
throws IntrospectionException {
275+
276+
super(propertyName, readMethod, writeMethod);
282277
}
283278

284279
@Override
@@ -297,11 +292,33 @@ public void setWriteMethod(@Nullable Method writeMethod) {
297292
this.writeMethod = writeMethod;
298293
}
299294

295+
public void addWriteMethod(Method writeMethod) {
296+
if (this.writeMethod != null) {
297+
this.alternativeWriteMethods.add(this.writeMethod);
298+
this.writeMethod = null;
299+
}
300+
this.alternativeWriteMethods.add(writeMethod);
301+
}
302+
300303
@Override
301304
@Nullable
302305
public Method getWriteMethod() {
306+
if (this.writeMethod == null && !this.alternativeWriteMethods.isEmpty()) {
307+
if (this.readMethod == null) {
308+
return this.alternativeWriteMethods.get(0);
309+
}
310+
else {
311+
for (Method method : this.alternativeWriteMethods) {
312+
if (this.readMethod.getReturnType().isAssignableFrom(method.getParameterTypes()[0])) {
313+
this.writeMethod = method;
314+
break;
315+
}
316+
}
317+
}
318+
}
303319
return this.writeMethod;
304320
}
305321
}
306322

323+
307324
}

Diff for: spring-beans/src/main/java/org/springframework/beans/SimpleBeanInfoFactory.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ class SimpleBeanInfoFactory implements BeanInfoFactory, Ordered {
4848
@Override
4949
@NonNull
5050
public BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException {
51-
Collection<PropertyDescriptor> pds = PropertyDescriptorUtils.determineBasicProperties(beanClass);
51+
Collection<? extends PropertyDescriptor> pds =
52+
PropertyDescriptorUtils.determineBasicProperties(beanClass);
53+
5254
return new SimpleBeanInfo() {
5355
@Override
5456
public PropertyDescriptor[] getPropertyDescriptors() {

Diff for: spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java

+28
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,16 @@ void setPropertyTypeMismatch() {
153153
assertThat(accessor.getPropertyValue("object")).isEqualTo(8);
154154
}
155155

156+
@Test
157+
void setterOverload() {
158+
SetterOverload target = new SetterOverload();
159+
BeanWrapper accessor = createAccessor(target);
160+
accessor.setPropertyValue("object", "a String");
161+
assertThat(target.value).isEqualTo("a String");
162+
assertThat(target.getObject()).isEqualTo("a String");
163+
assertThat(accessor.getPropertyValue("object")).isEqualTo("a String");
164+
}
165+
156166
@Test
157167
void propertyDescriptors() throws Exception {
158168
TestBean target = new TestBean();
@@ -348,6 +358,24 @@ public Integer getObject() {
348358
}
349359

350360

361+
public static class SetterOverload {
362+
363+
public String value;
364+
365+
public void setObject(Integer length) {
366+
this.value = length.toString();
367+
}
368+
369+
public void setObject(String object) {
370+
this.value = object;
371+
}
372+
373+
public String getObject() {
374+
return this.value;
375+
}
376+
}
377+
378+
351379
public static class GetterWithOptional {
352380

353381
public TestBean value;

Diff for: spring-context/src/main/java/org/springframework/format/datetime/standard/Jsr310DateTimeFormatAnnotationFormatterFactory.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -95,6 +95,8 @@ else if (formatter == DateTimeFormatter.ISO_DATE_TIME) {
9595
@Override
9696
@SuppressWarnings("unchecked")
9797
public Parser<?> getParser(DateTimeFormat annotation, Class<?> fieldType) {
98+
DateTimeFormatter formatter = getFormatter(annotation, fieldType);
99+
98100
List<String> resolvedFallbackPatterns = new ArrayList<>();
99101
for (String fallbackPattern : annotation.fallbackPatterns()) {
100102
String resolvedFallbackPattern = resolveEmbeddedValue(fallbackPattern);
@@ -103,7 +105,6 @@ public Parser<?> getParser(DateTimeFormat annotation, Class<?> fieldType) {
103105
}
104106
}
105107

106-
DateTimeFormatter formatter = getFormatter(annotation, fieldType);
107108
return new TemporalAccessorParser((Class<? extends TemporalAccessor>) fieldType,
108109
formatter, resolvedFallbackPatterns.toArray(new String[0]), annotation);
109110
}

0 commit comments

Comments
 (0)