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:
Dave Syer
2018-02-14 16:25:12 +00:00
parent c728cd4c01
commit ccd3953163
2 changed files with 42 additions and 6 deletions

View File

@@ -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) {

View File

@@ -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)