diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionType.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionType.java index 3ca0f6166..aee52a1f3 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionType.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionType.java @@ -99,7 +99,7 @@ public class FunctionType { public static boolean isWrapper(Type type) { if (type instanceof ParameterizedType) { - type = ((ParameterizedType)type).getRawType(); + type = ((ParameterizedType) type).getRawType(); } return Publisher.class.equals(type) || Flux.class.equals(type) || Mono.class.equals(type) || Optional.class.equals(type); @@ -222,13 +222,19 @@ public class FunctionType { private Class findType(ParamType paramType) { int index = paramType.isOutput() ? 1 : 0; Type type = this.type; - if (type instanceof Class) { - for (Type iface : ((Class) type).getGenericInterfaces()) { + boolean found = false; + while (!found && type instanceof Class && type != Object.class) { + Class clz = (Class) type; + for (Type iface : clz.getGenericInterfaces()) { if (iface.getTypeName().startsWith("java.util.function")) { type = iface; + found = true; break; } } + if (!found) { + type = clz.getSuperclass(); + } } Type param = extractType(type, paramType, index); if (param != null) { diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java index 5e9a49ba5..6dc0a93ac 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java @@ -539,14 +539,22 @@ public class ContextFunctionCatalogAutoConfiguration { param = new FunctionType(resolvable.getType()); } else { - Object bean = this.registry.getBean(name); - if (bean instanceof FunctionFactoryMetadata) { - FunctionFactoryMetadata factory = (FunctionFactoryMetadata) bean; - Type type = factory.getFactoryMethod().getGenericReturnType(); + Class beanClass = definition.getBeanClass(); + if (beanClass != null && !FunctionFactoryMetadata.class + .isAssignableFrom(beanClass)) { + Type type = beanClass; param = new FunctionType(type); } else { - param = new FunctionType(bean.getClass()); + Object bean = this.registry.getBean(name); + if (bean instanceof FunctionFactoryMetadata) { + FunctionFactoryMetadata factory = (FunctionFactoryMetadata) bean; + Type type = factory.getFactoryMethod().getGenericReturnType(); + param = new FunctionType(type); + } + else { + param = new FunctionType(bean.getClass()); + } } } } diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java index efed79032..437f18896 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfigurationTests.java @@ -123,6 +123,20 @@ public class ContextFunctionCatalogAutoConfigurationTests { .isEqualTo(Foo.class); } + @Test + public void configurationFunction() { + create(FunctionConfiguration.class); + assertThat(context.getBean("foos")).isInstanceOf(Function.class); + assertThat(catalog.>lookup(Function.class, "foos")) + .isInstanceOf(Function.class); + assertThat(inspector.getInputType(catalog.lookup(Function.class, "foos"))) + .isEqualTo(String.class); + assertThat(inspector.getOutputType(catalog.lookup(Function.class, "foos"))) + .isEqualTo(Foo.class); + assertThat(inspector.getInputWrapper(catalog.lookup(Function.class, "foos"))) + .isEqualTo(Flux.class); + } + @Test public void dependencyInjection() { create(DependencyInjectionConfiguration.class); @@ -558,6 +572,22 @@ public class ContextFunctionCatalogAutoConfigurationTests { } } + @EnableAutoConfiguration + @Configuration("foos") + protected static class FunctionConfiguration + implements Function, Flux> { + + @Override + public Flux apply(Flux flux) { + return flux.map(foo -> new Foo(value() + ": " + foo.toUpperCase())); + } + + @Bean + public String value() { + return "Hello"; + } + } + @EnableAutoConfiguration @Configuration @ComponentScan(basePackageClasses = FooConfiguration.class)