Discover function type from FactoryBean

* Fix spring-integration sample

* Added discoverFunctionTypeFromClass() method to FunctionTypeUtils

* A `FactoryBean` may produce a function instance as well.
Add a logic into `BeanFactoryAwareFunctionRegistry` to discover a function type from the `FactoryBean.getObjectType()`
This commit is contained in:
Oleg Zhurakousky
2019-09-25 10:24:07 -04:00
committed by Artem Bilan
parent bdd4320a59
commit 97bea81836
6 changed files with 84 additions and 9 deletions

View File

@@ -47,6 +47,7 @@ import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.cloud.function.context.FunctionCatalog;
@@ -188,6 +189,10 @@ public class BeanFactoryAwareFunctionRegistry
boolean beanDefinitionExists = false;
for (int i = 0; i < names.length && !beanDefinitionExists; i++) {
beanDefinitionExists = this.applicationContext.getBeanFactory().containsBeanDefinition(names[i]);
if (this.applicationContext.containsBean("&" + names[i])) {
Class<?> objectType = this.applicationContext.getBean("&" + names[i], FactoryBean.class).getObjectType();
return FunctionTypeUtils.discoverFunctionTypeFromClass(objectType);
}
}
if (!beanDefinitionExists) {
logger.info("BeanDefinition for function name(s) '" + Arrays.asList(names) +
@@ -430,7 +435,9 @@ public class BeanFactoryAwareFunctionRegistry
FunctionInvocationWrapper(Object target, Type functionType, String functionDefinition, String... acceptedOutputMimeTypes) {
this.target = target;
this.composed = !target.getClass().getName().contains("EnhancerBySpringCGLIB") && target.getClass().getDeclaredFields().length > 1;
this.composed = !target.getClass().getName().contains("$$EnhancerBySpringCGLIB")
&& !AopUtils.isAopProxy(target) && !AopUtils.isJdkDynamicProxy(target)
&& target.getClass().getDeclaredFields().length > 1;
this.functionType = functionType;
this.acceptedOutputMimeTypes = acceptedOutputMimeTypes;
this.functionDefinition = functionDefinition;

View File

@@ -105,7 +105,34 @@ public final class FunctionTypeUtils {
return methods.get(0);
}
public static Type getFunctionTypeFromFunctionMethod(Method functionMethod) {
public static Type discoverFunctionTypeFromClass(Class<?> functionalClass) {
Assert.isTrue(isFunctional(functionalClass), "Type must be one of Supplier, Function or Consumer");
Type[] generics = functionalClass.getGenericInterfaces();
if (ObjectUtils.isEmpty(generics)) {
return functionalClass;
}
else {
for (Type generic : generics) {
if (generic instanceof ParameterizedType) {
Class<?> rawClsss = (Class<?>) ((ParameterizedType) generic).getRawType();
if (rawClsss.isAssignableFrom(Function.class)
|| rawClsss.isAssignableFrom(Consumer.class)
|| rawClsss.isAssignableFrom(Supplier.class)) {
return generic;
}
else {
return discoverFunctionTypeFromClass(rawClsss);
}
}
else {
return discoverFunctionTypeFromClass((Class<?>) generic);
}
}
}
return null;
}
public static Type discoverFunctionTypeFromFunctionMethod(Method functionMethod) {
Assert.isTrue(
functionMethod.getName().equals("apply") ||
functionMethod.getName().equals("accept") ||