Commit 00ec268a authored by Oleg Zhurakousky's avatar Oleg Zhurakousky
Browse files

GH-420 Fix discovery of function type from class

Fix introspection over ScannedGenericBeanDefinition

Resolves #420
parent 69c158c7
Showing with 41 additions and 3 deletions
+41 -3
......@@ -81,13 +81,16 @@ public final class FunctionTypeUtils {
*/
public static Method discoverFunctionalMethod(Class<?> pojoFunctionClass) {
if (Supplier.class.isAssignableFrom(pojoFunctionClass)) {
return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> m.getName().equals("get")).findFirst().get();
return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic()
&& m.getName().equals("get")).findFirst().get();
}
else if (Consumer.class.isAssignableFrom(pojoFunctionClass) || BiConsumer.class.isAssignableFrom(pojoFunctionClass)) {
return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> m.getName().equals("accept")).findFirst().get();
return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic()
&& m.getName().equals("accept")).findFirst().get();
}
else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class.isAssignableFrom(pojoFunctionClass)) {
return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> m.getName().equals("apply")).findFirst().get();
return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic()
&& m.getName().equals("apply")).findFirst().get();
}
List<Method> methods = new ArrayList<>();
......
......@@ -28,7 +28,9 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
import org.springframework.cloud.function.core.FunctionFactoryMetadata;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.Resource;
import org.springframework.core.type.MethodMetadata;
......@@ -58,6 +60,15 @@ public abstract class FunctionContextUtils {
if (definition == null) {
return null;
}
else if (definition instanceof ScannedGenericBeanDefinition) {
try {
return FunctionTypeUtils.discoverFunctionTypeFromClass(definition.getBeanClass());
}
catch (Exception e) {
// ignore since name may not be actually resolved to a class in some cases
// java.lang.IllegalStateException: Bean class name [functions.Greeter] has not been resolved into an actual Class
}
}
Object source = definition.getSource();
......
......@@ -17,6 +17,7 @@
package org.springframework.cloud.function.context.catalog;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Date;
import java.util.List;
......@@ -44,6 +45,23 @@ import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unused")
public class FunctionTypeUtilsTests {
@Test
public void testFunctionTypeFrom() throws Exception {
Type type = FunctionTypeUtils.discoverFunctionTypeFromClass(SimpleConsumer.class);
assertThat(type).isInstanceOf(ParameterizedType.class);
Type wrapperType = ((ParameterizedType) type).getActualTypeArguments()[0];
assertThat(wrapperType).isInstanceOf(ParameterizedType.class);
assertThat(wrapperType.getTypeName()).contains("Flux");
Type innerWrapperType = ((ParameterizedType) wrapperType).getActualTypeArguments()[0];
assertThat(innerWrapperType).isInstanceOf(ParameterizedType.class);
assertThat(innerWrapperType.getTypeName()).contains("Message");
Type targetType = ((ParameterizedType) innerWrapperType).getActualTypeArguments()[0];
assertThat(targetType).isEqualTo(String.class);
System.out.println();
}
@Test
public void testInputCount() throws Exception {
int inputCount = FunctionTypeUtils.getInputCount(getReturnType("function"));
......@@ -205,4 +223,10 @@ public class FunctionTypeUtilsTests {
private interface MyMessageConsumer extends MessageConsumer<Date> {
}
public static class SimpleConsumer implements Consumer<Flux<Message<String>>> {
@Override
public void accept(Flux<Message<String>> messageFlux) {
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment