Skip to content

Commit

Permalink
Fix FunctionTypeUtils for FactoryBean
Browse files Browse the repository at this point in the history
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
  • Loading branch information
artembilan committed Dec 26, 2024
1 parent c1cb638 commit 5b4c557
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -78,6 +78,7 @@
*
* @author Oleg Zhurakousky
* @author Andrey Shlykov
* @author Artem Bilan
*
* @since 3.0
*/
Expand Down Expand Up @@ -444,6 +445,12 @@ else if (!(type instanceof ParameterizedType)) {
}
}
}
else if (type instanceof ParameterizedType) {
ResolvableType resolvableType = ResolvableType.forType(type);
if (FactoryBean.class.isAssignableFrom(resolvableType.toClass())) {
return resolvableType.getGeneric(0).getType();
}
}
return type;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,6 +54,7 @@
import reactor.util.function.Tuple3;
import reactor.util.function.Tuples;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.builder.SpringApplicationBuilder;
Expand Down Expand Up @@ -83,6 +84,7 @@
/**
*
* @author Oleg Zhurakousky
* @author Artem Bilan
*
*/
public class BeanFactoryAwareFunctionRegistryTests {
Expand Down Expand Up @@ -849,6 +851,14 @@ public void testArrayPayloadOnFluxFunction() throws Exception {
assertThat(result.size()).isEqualTo(3);
}

@Test
void functionFromFactoryBeanIsProperlyResolved() {
FunctionCatalog catalog = configureCatalog();
Function<Number, String> numberToStringFactoryBean = catalog.lookup("numberToStringFactoryBean");
assertThat(numberToStringFactoryBean).isNotNull();
assertThat(numberToStringFactoryBean.apply(1)).isEqualTo("1");
}

@Test
// see GH-707
public void testConcurrencyOnLookup() throws Exception {
Expand Down Expand Up @@ -1300,6 +1310,23 @@ public Consumer<Flux<String>> reactiveConsumer() {
public Consumer<Flux<Person>> reactivePojoConsumer() {
return flux -> flux.subscribe(v -> consumerInputRef.set(v));
}

@Bean
FactoryBean<Function<Number, String>> numberToStringFactoryBean() {
return new FactoryBean<>() {

@Override
public Function<Number, String> getObject() {
return Number::toString;
}

@Override
public Class<?> getObjectType() {
return Function.class;
}

};
}
}

@EnableAutoConfiguration
Expand Down

0 comments on commit 5b4c557

Please sign in to comment.