Cache result of isMessage() computation before function is wrapped
Otherwise you get the wrong result when you go back and ask later (but only if the bean is a singleton with no bean definition).
This commit is contained in:
@@ -474,6 +474,7 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
type = Function.class;
|
type = Function.class;
|
||||||
findType(target, ParamType.INPUT);
|
findType(target, ParamType.INPUT);
|
||||||
findType(target, ParamType.OUTPUT);
|
findType(target, ParamType.OUTPUT);
|
||||||
|
isMessage(target); // cache wrapper types
|
||||||
registration.target(target((Function<?, ?>) target, key));
|
registration.target(target((Function<?, ?>) target, key));
|
||||||
for (String name : registration.getNames()) {
|
for (String name : registration.getNames()) {
|
||||||
this.functions.put(name, (Function<?, ?>) registration.getTarget());
|
this.functions.put(name, (Function<?, ?>) registration.getTarget());
|
||||||
@@ -559,10 +560,11 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
return FunctionInspector
|
return FunctionInspector
|
||||||
.isWrapper(findType(function, ParamType.INPUT_WRAPPER))
|
.isWrapper(findType(function, ParamType.INPUT_WRAPPER))
|
||||||
|| FunctionInspector
|
|| FunctionInspector
|
||||||
.isWrapper(findType(function, ParamType.OUTPUT_WRAPPER));
|
.isWrapper(findType(function, ParamType.OUTPUT_WRAPPER));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> findType(String name, AbstractBeanDefinition definition, ParamType paramType) {
|
private Class<?> findType(String name, AbstractBeanDefinition definition,
|
||||||
|
ParamType paramType) {
|
||||||
Object source = definition.getSource();
|
Object source = definition.getSource();
|
||||||
Type param = null;
|
Type param = null;
|
||||||
// Start by assuming output -> Function
|
// Start by assuming output -> Function
|
||||||
@@ -710,10 +712,12 @@ public class ContextFunctionCatalogAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMessage(Object function) {
|
private boolean isMessage(Object function) {
|
||||||
return Message.class
|
Class<?> inputType = findType(function, ParamType.INPUT_INNER_WRAPPER);
|
||||||
.isAssignableFrom(findType(function, ParamType.INPUT_INNER_WRAPPER))
|
Class<?> outputType = findType(function, ParamType.OUTPUT_INNER_WRAPPER);
|
||||||
|| Message.class.isAssignableFrom(
|
return inputType.getName().startsWith(Message.class.getName())
|
||||||
findType(function, ParamType.OUTPUT_INNER_WRAPPER));
|
|| Message.class.isAssignableFrom(inputType)
|
||||||
|
|| outputType.getName().startsWith(Message.class.getName())
|
||||||
|
|| Message.class.isAssignableFrom(outputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> findType(Object function, ParamType type) {
|
private Class<?> findType(Object function, ParamType type) {
|
||||||
|
|||||||
@@ -233,6 +233,18 @@ public class ContextFunctionCatalogAutoConfigurationTests {
|
|||||||
.isAssignableFrom(Integer.class);
|
.isAssignableFrom(Integer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singletonMessageFunction() {
|
||||||
|
create(SingletonMessageConfiguration.class);
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(Function.class);
|
||||||
|
assertThat(catalog.lookupFunction("function")).isInstanceOf(Function.class);
|
||||||
|
assertThat(inspector.getInputType(catalog.lookupFunction("function")))
|
||||||
|
.isAssignableFrom(Integer.class);
|
||||||
|
assertThat(inspector.getInputWrapper(catalog.lookupFunction("function")))
|
||||||
|
.isAssignableFrom(Integer.class);
|
||||||
|
assertThat(inspector.isMessage(catalog.lookupFunction("function"))).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nonParametericTypeFunction() {
|
public void nonParametericTypeFunction() {
|
||||||
create(NonParametricTypeSingletonConfiguration.class);
|
create(NonParametricTypeSingletonConfiguration.class);
|
||||||
@@ -529,6 +541,17 @@ public class ContextFunctionCatalogAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@Configuration
|
||||||
|
protected static class SingletonMessageConfiguration implements BeanFactoryPostProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||||
|
throws BeansException {
|
||||||
|
beanFactory.registerSingleton("function", new SingletonMessageFunction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EnableAutoConfiguration
|
@EnableAutoConfiguration
|
||||||
@Configuration
|
@Configuration
|
||||||
protected static class NonParametricTypeSingletonConfiguration {
|
protected static class NonParametricTypeSingletonConfiguration {
|
||||||
@@ -547,6 +570,15 @@ public class ContextFunctionCatalogAutoConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static class SingletonMessageFunction implements Function<Message<Integer>, Message<String>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Message<String> apply(Message<Integer> input) {
|
||||||
|
return MessageBuilder.withPayload("value=" + input.getPayload()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@EnableAutoConfiguration
|
@EnableAutoConfiguration
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan(basePackageClasses = GenericFunction.class)
|
@ComponentScan(basePackageClasses = GenericFunction.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user