Add other annotation processors to functional context
This commit is contained in:
@@ -22,7 +22,6 @@ import com.google.gson.Gson;
|
|||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
@@ -39,6 +38,7 @@ import org.springframework.context.ApplicationContextInitializer;
|
|||||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
@@ -108,10 +108,13 @@ public class ContextFunctionCatalogInitializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!context.getBeanFactory().containsBean(
|
if (!context.getBeanFactory().containsBean(
|
||||||
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||||
|
// Switch off the ConfigurationClassPostProcessor
|
||||||
context.registerBean(
|
context.registerBean(
|
||||||
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME,
|
AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,
|
||||||
AutowiredAnnotationBeanPostProcessor.class);
|
DummyProcessor.class, () -> new DummyProcessor());
|
||||||
|
// But switch on other annotation processing
|
||||||
|
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
|
||||||
}
|
}
|
||||||
if (!context.getBeanFactory()
|
if (!context.getBeanFactory()
|
||||||
.containsBean(ConfigurationBeanFactoryMetadata.BEAN_NAME)) {
|
.containsBean(ConfigurationBeanFactoryMetadata.BEAN_NAME)) {
|
||||||
@@ -221,4 +224,8 @@ public class ContextFunctionCatalogInitializer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DummyProcessor {
|
||||||
|
public void setMetadataReaderFactory(MetadataReaderFactory obj) {}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,25 +16,24 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.function.context.config;
|
package org.springframework.cloud.function.context.config;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.atomic.AtomicStampedReference;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import org.springframework.cloud.function.context.FunctionRegistration;
|
import org.springframework.cloud.function.context.FunctionRegistration;
|
||||||
import org.springframework.cloud.function.context.FunctionType;
|
import org.springframework.cloud.function.context.FunctionType;
|
||||||
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration.BeanFactoryFunctionCatalog;
|
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration.BeanFactoryFunctionCatalog;
|
||||||
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration.ContextFunctionRegistry;
|
import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration.ContextFunctionRegistry;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ package org.springframework.cloud.function.context.config;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@@ -26,10 +28,13 @@ import java.util.function.Supplier;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.cloud.function.context.FunctionCatalog;
|
import org.springframework.cloud.function.context.FunctionCatalog;
|
||||||
import org.springframework.cloud.function.context.FunctionRegistration;
|
import org.springframework.cloud.function.context.FunctionRegistration;
|
||||||
import org.springframework.cloud.function.context.FunctionType;
|
import org.springframework.cloud.function.context.FunctionType;
|
||||||
@@ -37,6 +42,8 @@ import org.springframework.cloud.function.context.catalog.FunctionInspector;
|
|||||||
import org.springframework.context.ApplicationContextInitializer;
|
import org.springframework.context.ApplicationContextInitializer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
|
import org.springframework.core.env.MapPropertySource;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -66,6 +73,40 @@ public class ContextFunctionCatalogInitializerTests {
|
|||||||
assertThat(context.getBean("function")).isInstanceOf(FunctionRegistration.class);
|
assertThat(context.getBean("function")).isInstanceOf(FunctionRegistration.class);
|
||||||
assertThat((Function<?, ?>) catalog.lookup(Function.class, "function"))
|
assertThat((Function<?, ?>) catalog.lookup(Function.class, "function"))
|
||||||
.isInstanceOf(Function.class);
|
.isInstanceOf(Function.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void properties() {
|
||||||
|
create(PropertiesConfiguration.class, "app.greeting=hello");
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(FunctionRegistration.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Function<Flux<String>, Flux<String>> function = (Function<Flux<String>, Flux<String>>) catalog
|
||||||
|
.lookup(Function.class, "function");
|
||||||
|
assertThat(function).isInstanceOf(Function.class);
|
||||||
|
assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("hello foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void value() {
|
||||||
|
create(ValueConfiguration.class, "app.greeting=hello");
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(FunctionRegistration.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Function<Flux<String>, Flux<String>> function = (Function<Flux<String>, Flux<String>>) catalog
|
||||||
|
.lookup(Function.class, "function");
|
||||||
|
assertThat(function).isInstanceOf(Function.class);
|
||||||
|
assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("hello foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void compose() {
|
||||||
|
create(SimpleConfiguration.class);
|
||||||
|
assertThat(context.getBean("function")).isInstanceOf(FunctionRegistration.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Supplier<Flux<String>> supplier = (Supplier<Flux<String>>) catalog
|
||||||
|
.lookup(Supplier.class, "supplier|function");
|
||||||
|
assertThat(supplier).isInstanceOf(Supplier.class);
|
||||||
|
assertThat(supplier.get().blockFirst()).isEqualTo("HELLO");
|
||||||
// TODO: support for function composition
|
// TODO: support for function composition
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +194,17 @@ public class ContextFunctionCatalogInitializerTests {
|
|||||||
private void create(ApplicationContextInitializer<GenericApplicationContext>[] types,
|
private void create(ApplicationContextInitializer<GenericApplicationContext>[] types,
|
||||||
String... props) {
|
String... props) {
|
||||||
context = new GenericApplicationContext();
|
context = new GenericApplicationContext();
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
for (String prop : props) {
|
||||||
|
String[] array = StringUtils.delimitedListToStringArray(prop, "=");
|
||||||
|
String key = array[0];
|
||||||
|
String value = array.length > 1 ? array[1] : "";
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
if (!map.isEmpty()) {
|
||||||
|
context.getEnvironment().getPropertySources()
|
||||||
|
.addFirst(new MapPropertySource("testProperties", map));
|
||||||
|
}
|
||||||
for (ApplicationContextInitializer<GenericApplicationContext> type : types) {
|
for (ApplicationContextInitializer<GenericApplicationContext> type : types) {
|
||||||
type.initialize(context);
|
type.initialize(context);
|
||||||
}
|
}
|
||||||
@@ -222,6 +274,56 @@ public class ContextFunctionCatalogInitializerTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigurationProperties("app")
|
||||||
|
protected static class PropertiesConfiguration
|
||||||
|
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||||
|
|
||||||
|
private String greeting;
|
||||||
|
|
||||||
|
public String getGreeting() {
|
||||||
|
return this.greeting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGreeting(String greeting) {
|
||||||
|
this.greeting = greeting;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(GenericApplicationContext context) {
|
||||||
|
context.registerBean("function", FunctionRegistration.class,
|
||||||
|
() -> new FunctionRegistration<>(function()).type(
|
||||||
|
FunctionType.from(String.class).to(String.class).getType()));
|
||||||
|
context.registerBean(PropertiesConfiguration.class, () -> this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Function<String, String> function() {
|
||||||
|
return value -> greeting + " " + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class ValueConfiguration
|
||||||
|
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||||
|
|
||||||
|
@Value("${app.greeting}")
|
||||||
|
private String greeting;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(GenericApplicationContext context) {
|
||||||
|
context.registerBean("function", FunctionRegistration.class,
|
||||||
|
() -> new FunctionRegistration<>(function()).type(
|
||||||
|
FunctionType.from(String.class).to(String.class).getType()));
|
||||||
|
context.registerBean(ValueConfiguration.class, () -> this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Function<String, String> function() {
|
||||||
|
return value -> greeting + " " + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected static class GsonConfiguration
|
protected static class GsonConfiguration
|
||||||
implements ApplicationContextInitializer<GenericApplicationContext> {
|
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user