Resort to reflection if the function is not a @Bean

Beans that are not created from a @Bean factory method do not have
the same kind of metadata. This change uses relection to extract
the target type from the bean definition if all else fails.
This commit is contained in:
Dave Syer
2017-03-10 17:40:05 +00:00
parent 2ee97721ab
commit 5ace9b764b

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.function.context;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
@@ -48,6 +49,7 @@ import org.springframework.core.ResolvableType;
import org.springframework.core.type.StandardMethodMetadata;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import reactor.core.publisher.Flux;
@@ -246,10 +248,19 @@ public class ContextFunctionCatalogAutoConfiguration {
private Class<?> findType(RootBeanDefinition definition, int index) {
StandardMethodMetadata source = (StandardMethodMetadata) definition
.getSource();
ParameterizedType type = (ParameterizedType) (source.getIntrospectedMethod()
.getGenericReturnType());
type = (ParameterizedType) type.getActualTypeArguments()[index];
Type param = type.getActualTypeArguments()[0];
Type param;
if (source instanceof StandardMethodMetadata) {
ParameterizedType type;
type = (ParameterizedType) (source.getIntrospectedMethod()
.getGenericReturnType());
type = (ParameterizedType) type.getActualTypeArguments()[index];
param = type.getActualTypeArguments()[0];
}
else {
ResolvableType resolvable = (ResolvableType) getField(definition,
"targetType");
param = resolvable.getGeneric(index).getGeneric(0).getType();
}
if (param instanceof ParameterizedType) {
ParameterizedType concrete = (ParameterizedType) param;
param = concrete.getRawType();
@@ -258,6 +269,12 @@ public class ContextFunctionCatalogAutoConfiguration {
registry.getClass().getClassLoader());
}
private Object getField(Object target, String name) {
Field field = ReflectionUtils.findField(target.getClass(), name);
ReflectionUtils.makeAccessible(field);
return ReflectionUtils.getField(field, target);
}
private Class<?> findType(String name) {
return findType((RootBeanDefinition) registry.getBeanDefinition(name), 0);
}