diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java index 9ba787ff4..8f90e76f2 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java @@ -29,6 +29,7 @@ import java.util.function.Supplier; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -37,6 +38,8 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.function.registry.FunctionCatalog; +import org.springframework.cloud.function.support.FluxFunction; +import org.springframework.cloud.function.support.FunctionUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.ResolvableType; @@ -115,6 +118,9 @@ public class ContextFunctionCatalogAutoConfiguration { .get(key); result.put(key, wrapFunction(function, mapper, key)); } + else if (!isFluxFunction(key, functions.get(key))) { + result.put(key, new FluxFunction(functions.get(key))); + } else { result.put(key, functions.get(key)); } @@ -154,6 +160,25 @@ public class ContextFunctionCatalogAutoConfiguration { } } + private boolean isFluxFunction(String name, Function function) { + if (this.registry.containsBeanDefinition(name)) { + BeanDefinition beanDefinition = this.registry.getBeanDefinition(name); + Object source = beanDefinition.getSource(); + if (source instanceof StandardMethodMetadata) { + StandardMethodMetadata metadata = (StandardMethodMetadata) source; + Type returnType = metadata.getIntrospectedMethod().getGenericReturnType(); + if (returnType instanceof ParameterizedType) { + Type[] types = ((ParameterizedType) returnType).getActualTypeArguments(); + if (types != null && types.length == 2) { + return (types[0].getTypeName().startsWith(Flux.class.getName()) + && types[1].getTypeName().startsWith(Flux.class.getName())); + } + } + } + } + return FunctionUtils.isFluxFunction(function); + } + private boolean isGenericSupplier(ConfigurableListableBeanFactory factory, String name) { return factory.isTypeMatch(name, diff --git a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/FunctionUtils.java b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/FunctionUtils.java index 20d793cc1..82dda14bf 100644 --- a/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/FunctionUtils.java +++ b/spring-cloud-function-core/src/main/java/org/springframework/cloud/function/support/FunctionUtils.java @@ -58,7 +58,7 @@ public abstract class FunctionUtils { } String[] types = getParameterizedTypeNames(function, Function.class); if (ObjectUtils.isEmpty(types) || types.length != 2) { - return true; + return false; } return (types[0].startsWith(FLUX_CLASS_NAME) && types[1].startsWith(FLUX_CLASS_NAME)); } diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionController.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionController.java index 246f6c146..49b7db408 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionController.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/FunctionController.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.cloud.function.registry.FunctionCatalog; -import org.springframework.cloud.function.support.FluxFunction; import org.springframework.cloud.function.support.FluxSupplier; import org.springframework.cloud.function.support.FunctionUtils; import org.springframework.web.bind.annotation.GetMapping; @@ -56,11 +55,8 @@ public class FunctionController { @PostMapping(path = "/{name}") public Flux function(@PathVariable String name, @RequestBody Flux body) { - Function function = functions.lookupFunction(name); + Function, Flux> function = functions.lookupFunction(name); if (function != null) { - if (!FunctionUtils.isFluxFunction(function)) { - function = new FluxFunction(function); - } @SuppressWarnings("unchecked") Flux result = (Flux) function.apply(body); return debug ? result.log() : result;