Merge branch '2.3.x'

Closes gh-24425
pull/24453/head
Phillip Webb 4 years ago
commit 112503058a

@ -21,9 +21,12 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -126,13 +129,19 @@ class JavaBeanBinder implements DataObjectBinder {
private void addProperties(Class<?> type) { private void addProperties(Class<?> type) {
while (type != null && !Object.class.equals(type)) { while (type != null && !Object.class.equals(type)) {
Method[] declaredMethods = type.getDeclaredMethods(); Method[] declaredMethods = getSorted(type, Class::getDeclaredMethods, Method::getName);
Field[] declaredFields = type.getDeclaredFields(); Field[] declaredFields = getSorted(type, Class::getDeclaredFields, Field::getName);
addProperties(declaredMethods, declaredFields); addProperties(declaredMethods, declaredFields);
type = type.getSuperclass(); type = type.getSuperclass();
} }
} }
private <S, E> E[] getSorted(S source, Function<S, E[]> elements, Function<E, String> name) {
E[] result = elements.apply(source);
Arrays.sort(result, Comparator.comparing(name));
return result;
}
protected void addProperties(Method[] declaredMethods, Field[] declaredFields) { protected void addProperties(Method[] declaredMethods, Field[] declaredFields) {
for (int i = 0; i < declaredMethods.length; i++) { for (int i = 0; i < declaredMethods.length; i++) {
if (!isCandidate(declaredMethods[i])) { if (!isCandidate(declaredMethods[i])) {

@ -26,6 +26,7 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -540,6 +541,19 @@ class JavaBeanBinderTests {
assertThat(bean.getProperty()).isEqualTo("test"); assertThat(bean.getProperty()).isEqualTo("test");
} }
@Test
void bindUsesConsistentPropertyOrder() {
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("foo.gamma", "0");
source.put("foo.alpha", "0");
source.put("foo.beta", "0");
this.sources.add(source);
PropertyOrderBean bean = this.binder.bind("foo", Bindable.of(PropertyOrderBean.class)).get();
assertThat(bean.getAlpha()).isEqualTo(0);
assertThat(bean.getBeta()).isEqualTo(1);
assertThat(bean.getGamma()).isEqualTo(2);
}
@Test // gh-23007 @Test // gh-23007
void bindWhenBeanWithGetSetIsMethodsFoundUsesGetterThatMatchesSetter() { void bindWhenBeanWithGetSetIsMethodsFoundUsesGetterThatMatchesSetter() {
MockConfigurationPropertySource source = new MockConfigurationPropertySource(); MockConfigurationPropertySource source = new MockConfigurationPropertySource();
@ -1086,4 +1100,40 @@ class JavaBeanBinderTests {
} }
static class PropertyOrderBean {
static AtomicInteger atomic = new AtomicInteger();
private int alpha;
private int beta;
private int gamma;
int getAlpha() {
return this.alpha;
}
void setAlpha(int alpha) {
this.alpha = alpha + atomic.getAndIncrement();
}
int getBeta() {
return this.beta;
}
void setBeta(int beta) {
this.beta = beta + atomic.getAndIncrement();
}
int getGamma() {
return this.gamma;
}
void setGamma(int gamma) {
this.gamma = gamma + atomic.getAndIncrement();
}
}
} }

Loading…
Cancel
Save