Skip to content

Commit 5b4c557

Browse files
committed
Fix FunctionTypeUtils for FactoryBean
The function bean can be declared as a `FactoryBean`, for example with Spring Integration's `GatewayProxyFactoryBean`. See `LogConsumerConfiguration` in Spring Functions Catalog project. * Fix `FunctionTypeUtils` to react to the `ParameterizedType` and check its assignments against `Factory` bean. Then resolves its generic to the proper target function type. * Add `BeanFactoryAwareFunctionRegistryTests.functionFromFactoryBeanIsProperlyResolved()` to verify that `FactoryBean<Function<?, ?>>` is resolved properly
1 parent c1cb638 commit 5b4c557

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtils.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2022 the original author or authors.
2+
* Copyright 2019-2025 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.
@@ -78,6 +78,7 @@
7878
*
7979
* @author Oleg Zhurakousky
8080
* @author Andrey Shlykov
81+
* @author Artem Bilan
8182
*
8283
* @since 3.0
8384
*/
@@ -444,6 +445,12 @@ else if (!(type instanceof ParameterizedType)) {
444445
}
445446
}
446447
}
448+
else if (type instanceof ParameterizedType) {
449+
ResolvableType resolvableType = ResolvableType.forType(type);
450+
if (FactoryBean.class.isAssignableFrom(resolvableType.toClass())) {
451+
return resolvableType.getGeneric(0).getType();
452+
}
453+
}
447454
return type;
448455
}
449456

spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2021 the original author or authors.
2+
* Copyright 2019-2025 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.
@@ -54,6 +54,7 @@
5454
import reactor.util.function.Tuple3;
5555
import reactor.util.function.Tuples;
5656

57+
import org.springframework.beans.factory.FactoryBean;
5758
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5859
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
5960
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -83,6 +84,7 @@
8384
/**
8485
*
8586
* @author Oleg Zhurakousky
87+
* @author Artem Bilan
8688
*
8789
*/
8890
public class BeanFactoryAwareFunctionRegistryTests {
@@ -849,6 +851,14 @@ public void testArrayPayloadOnFluxFunction() throws Exception {
849851
assertThat(result.size()).isEqualTo(3);
850852
}
851853

854+
@Test
855+
void functionFromFactoryBeanIsProperlyResolved() {
856+
FunctionCatalog catalog = configureCatalog();
857+
Function<Number, String> numberToStringFactoryBean = catalog.lookup("numberToStringFactoryBean");
858+
assertThat(numberToStringFactoryBean).isNotNull();
859+
assertThat(numberToStringFactoryBean.apply(1)).isEqualTo("1");
860+
}
861+
852862
@Test
853863
// see GH-707
854864
public void testConcurrencyOnLookup() throws Exception {
@@ -1300,6 +1310,23 @@ public Consumer<Flux<String>> reactiveConsumer() {
13001310
public Consumer<Flux<Person>> reactivePojoConsumer() {
13011311
return flux -> flux.subscribe(v -> consumerInputRef.set(v));
13021312
}
1313+
1314+
@Bean
1315+
FactoryBean<Function<Number, String>> numberToStringFactoryBean() {
1316+
return new FactoryBean<>() {
1317+
1318+
@Override
1319+
public Function<Number, String> getObject() {
1320+
return Number::toString;
1321+
}
1322+
1323+
@Override
1324+
public Class<?> getObjectType() {
1325+
return Function.class;
1326+
}
1327+
1328+
};
1329+
}
13031330
}
13041331

13051332
@EnableAutoConfiguration

0 commit comments

Comments
 (0)