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
This commit is contained in:
committed by
Oleg Zhurakousky
parent
93f0c5e358
commit
5c92db4f80
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -63,6 +63,7 @@ import org.springframework.util.StringUtils;
|
|||||||
*
|
*
|
||||||
* @author Oleg Zhurakousky
|
* @author Oleg Zhurakousky
|
||||||
* @author Andrey Shlykov
|
* @author Andrey Shlykov
|
||||||
|
* @author Artem Bilan
|
||||||
*
|
*
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@@ -382,6 +383,12 @@ public final class FunctionTypeUtils {
|
|||||||
type = FunctionContextUtils.findType(applicationContext.getBeanFactory(), beanDefinitionName);
|
type = FunctionContextUtils.findType(applicationContext.getBeanFactory(), beanDefinitionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type instanceof ParameterizedType) {
|
||||||
|
ResolvableType resolvableType = ResolvableType.forType(type);
|
||||||
|
if (FactoryBean.class.isAssignableFrom(resolvableType.toClass())) {
|
||||||
|
return resolvableType.getGeneric(0).getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -54,6 +54,7 @@ import reactor.util.function.Tuple2;
|
|||||||
import reactor.util.function.Tuple3;
|
import reactor.util.function.Tuple3;
|
||||||
import reactor.util.function.Tuples;
|
import reactor.util.function.Tuples;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
@@ -85,6 +86,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Oleg Zhurakousky
|
* @author Oleg Zhurakousky
|
||||||
|
* @author Artem Bilan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BeanFactoryAwareFunctionRegistryTests {
|
public class BeanFactoryAwareFunctionRegistryTests {
|
||||||
@@ -891,6 +893,14 @@ public class BeanFactoryAwareFunctionRegistryTests {
|
|||||||
assertThat(result.size()).isEqualTo(3);
|
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
|
@Test
|
||||||
// see GH-707
|
// see GH-707
|
||||||
public void testConcurrencyOnLookup() throws Exception {
|
public void testConcurrencyOnLookup() throws Exception {
|
||||||
@@ -1342,6 +1352,23 @@ public class BeanFactoryAwareFunctionRegistryTests {
|
|||||||
public Consumer<Flux<Person>> reactivePojoConsumer() {
|
public Consumer<Flux<Person>> reactivePojoConsumer() {
|
||||||
return flux -> flux.subscribe(v -> consumerInputRef.set(v));
|
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
|
@EnableAutoConfiguration
|
||||||
|
|||||||
Reference in New Issue
Block a user