Skip to content

Commit 2e57603

Browse files
committed
Try type conversion for unique fallback write method as well
Closes gh-32329 See gh-32159
1 parent be45481 commit 2e57603

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

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

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -21,6 +21,7 @@
2121

2222
import org.apache.commons.logging.LogFactory;
2323

24+
import org.springframework.core.MethodParameter;
2425
import org.springframework.core.ResolvableType;
2526
import org.springframework.core.convert.TypeDescriptor;
2627
import org.springframework.lang.Nullable;
@@ -283,16 +284,25 @@ public void setValue(@Nullable Object value) throws Exception {
283284

284285
@Override
285286
public boolean setValueFallbackIfPossible(@Nullable Object value) {
286-
Method writeMethod = this.pd.getWriteMethodFallback(value != null ? value.getClass() : null);
287-
if (writeMethod != null) {
288-
ReflectionUtils.makeAccessible(writeMethod);
289-
try {
287+
try {
288+
Method writeMethod = this.pd.getWriteMethodFallback(value != null ? value.getClass() : null);
289+
if (writeMethod == null) {
290+
writeMethod = this.pd.getUniqueWriteMethodFallback();
291+
if (writeMethod != null) {
292+
// Conversion necessary as we would otherwise have received the method
293+
// from the type-matching getWriteMethodFallback call above already
294+
value = convertForProperty(this.pd.getName(), null, value,
295+
new TypeDescriptor(new MethodParameter(writeMethod, 0)));
296+
}
297+
}
298+
if (writeMethod != null) {
299+
ReflectionUtils.makeAccessible(writeMethod);
290300
writeMethod.invoke(getWrappedInstance(), value);
291301
return true;
292302
}
293-
catch (Exception ex) {
294-
LogFactory.getLog(BeanPropertyHandler.class).debug("Write method fallback failed", ex);
295-
}
303+
}
304+
catch (Exception ex) {
305+
LogFactory.getLog(BeanPropertyHandler.class).debug("Write method fallback failed", ex);
296306
}
297307
return false;
298308
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ public Method getWriteMethodFallback(@Nullable Class<?> valueType) {
171171
return null;
172172
}
173173

174+
@Nullable
175+
public Method getUniqueWriteMethodFallback() {
176+
if (this.ambiguousWriteMethods != null && this.ambiguousWriteMethods.size() == 1) {
177+
return this.ambiguousWriteMethods.iterator().next();
178+
}
179+
return null;
180+
}
181+
174182
public boolean hasUniqueWriteMethod() {
175183
return (this.writeMethod != null && this.ambiguousWriteMethods == null);
176184
}

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

+9-4
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,11 @@ void withOverloadedSetters() {
13421342
rbd.getPropertyValues().add("value", Duration.ofSeconds(1000));
13431343
lbf.registerBeanDefinition("overloaded", rbd);
13441344
assertThat(lbf.getBean(SetterOverload.class).getObject()).isEqualTo("1000s");
1345+
1346+
rbd = new RootBeanDefinition(SetterOverload.class);
1347+
rbd.getPropertyValues().add("value", "1000");
1348+
lbf.registerBeanDefinition("overloaded", rbd);
1349+
assertThat(lbf.getBean(SetterOverload.class).getObject()).isEqualTo("1000i");
13451350
}
13461351

13471352
@Test
@@ -3369,13 +3374,13 @@ public String getObject() {
33693374
return this.value;
33703375
}
33713376

3372-
public void setValue(int length) {
3373-
this.value = length + "i";
3374-
}
3375-
33763377
public void setValue(Duration duration) {
33773378
this.value = duration.getSeconds() + "s";
33783379
}
3380+
3381+
public void setValue(int length) {
3382+
this.value = length + "i";
3383+
}
33793384
}
33803385

33813386

0 commit comments

Comments
 (0)