Skip to content

Commit 069d6d3

Browse files
committed
Propagate getFactoryMethod() when using InstanceSupplier.andThen()
Update `InstanceSupplier.andThen` to propagate the result of `getFactoryMethod()`. See gh-28748
1 parent 3ae1b9b commit 069d6d3

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/InstanceSupplier.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,19 @@ default Method getFactoryMethod() {
7575
default <V> InstanceSupplier<V> andThen(
7676
ThrowingBiFunction<RegisteredBean, ? super T, ? extends V> after) {
7777
Assert.notNull(after, "After must not be null");
78-
return registeredBean -> after.applyWithException(registeredBean,
79-
get(registeredBean));
78+
return new InstanceSupplier<V>() {
79+
80+
@Override
81+
public V get(RegisteredBean registeredBean) throws Exception {
82+
return after.applyWithException(registeredBean, InstanceSupplier.this.get(registeredBean));
83+
}
84+
85+
@Override
86+
public Method getFactoryMethod() {
87+
return InstanceSupplier.this.getFactoryMethod();
88+
}
89+
90+
};
8091
}
8192

8293
/**
@@ -94,6 +105,35 @@ static <T> InstanceSupplier<T> using(ThrowingSupplier<T> supplier) {
94105
return registeredBean -> supplier.getWithException();
95106
}
96107

108+
/**
109+
* Factory method to create an {@link InstanceSupplier} from a
110+
* {@link ThrowingSupplier}.
111+
* @param <T> the type of instance supplied by this supplier
112+
* @param factoryMethod the factory method being used
113+
* @param supplier the source supplier
114+
* @return a new {@link InstanceSupplier}
115+
*/
116+
static <T> InstanceSupplier<T> using(@Nullable Method factoryMethod, ThrowingSupplier<T> supplier) {
117+
Assert.notNull(supplier, "Supplier must not be null");
118+
if (supplier instanceof InstanceSupplier<T> instanceSupplier
119+
&& instanceSupplier.getFactoryMethod() == factoryMethod) {
120+
return instanceSupplier;
121+
}
122+
return new InstanceSupplier<T>() {
123+
124+
@Override
125+
public T get(RegisteredBean registeredBean) throws Exception {
126+
return supplier.getWithException();
127+
}
128+
129+
@Override
130+
public Method getFactoryMethod() {
131+
return factoryMethod;
132+
}
133+
134+
};
135+
}
136+
97137
/**
98138
* Lambda friendly method that can be used to create a
99139
* {@link InstanceSupplier} and add post processors in a single call. For

spring-beans/src/test/java/org/springframework/beans/factory/support/InstanceSupplierTests.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.beans.factory.support;
1818

19+
import java.lang.reflect.Method;
20+
1921
import org.junit.jupiter.api.Test;
2022

2123
import org.springframework.util.function.ThrowingBiFunction;
@@ -55,21 +57,31 @@ void getReturnsResult() throws Exception {
5557
}
5658

5759
@Test
58-
void andThenWithBiFunctionWhenFunctionIsNullThrowsException() {
60+
void andThenWhenFunctionIsNullThrowsException() {
5961
InstanceSupplier<String> supplier = registeredBean -> "test";
6062
ThrowingBiFunction<RegisteredBean, String, String> after = null;
6163
assertThatIllegalArgumentException().isThrownBy(() -> supplier.andThen(after))
6264
.withMessage("After must not be null");
6365
}
6466

6567
@Test
66-
void andThenWithBiFunctionAppliesFunctionToObtainResult() throws Exception {
68+
void andThenAppliesFunctionToObtainResult() throws Exception {
6769
InstanceSupplier<String> supplier = registeredBean -> "bean";
6870
supplier = supplier.andThen(
6971
(registeredBean, string) -> registeredBean.getBeanName() + "-" + string);
7072
assertThat(supplier.get(this.registeredBean)).isEqualTo("test-bean");
7173
}
7274

75+
@Test
76+
void andThenWhenInstanceSupplierHasFactoryMethod() throws Exception {
77+
Method factoryMethod = getClass().getDeclaredMethod("andThenWhenInstanceSupplierHasFactoryMethod");
78+
InstanceSupplier<String> supplier = InstanceSupplier.using(factoryMethod, () -> "bean");
79+
supplier = supplier.andThen(
80+
(registeredBean, string) -> registeredBean.getBeanName() + "-" + string);
81+
assertThat(supplier.get(this.registeredBean)).isEqualTo("test-bean");
82+
assertThat(supplier.getFactoryMethod()).isSameAs(factoryMethod);
83+
}
84+
7385
@Test
7486
void ofSupplierWhenInstanceSupplierReturnsSameInstance() {
7587
InstanceSupplier<String> supplier = registeredBean -> "test";

0 commit comments

Comments
 (0)