Convert Consumer<Foo> to Function<Flux<Foo>,Mono<Void>>

This results in a better experience for users because the consumer
that they write is only applied to a Flux that is subscribed to
by the framework once. It gives better control over the flow of
foos, e.g. if some component wants to subscribe on a thread.
This commit is contained in:
Dave Syer
2018-03-26 10:06:13 +01:00
parent a1b624b28a
commit 5aeba1ea96
13 changed files with 144 additions and 76 deletions

View File

@@ -29,6 +29,7 @@ import java.util.jar.Manifest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.reactivestreams.Publisher;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,7 +50,7 @@ public class SpringFunctionInitializer implements Closeable {
private final Class<?> configurationClass;
private Function<Flux<?>, Flux<?>> function;
private Function<Flux<?>, Publisher<?>> function;
private Consumer<Flux<?>> consumer;
@@ -104,16 +105,20 @@ public class SpringFunctionInitializer implements Closeable {
if (defaultName) {
name = "consumer";
}
this.consumer = this.catalog.lookup(Consumer.class, name);
if (this.consumer == null) {
if (defaultName) {
name = "supplier";
this.function = this.catalog.lookup(Function.class, name);
if (this.function == null) {
this.consumer = this.catalog.lookup(Consumer.class, name);
if (this.consumer == null) {
if (defaultName) {
name = "supplier";
}
this.supplier = this.catalog.lookup(Supplier.class, name);
}
this.supplier = this.catalog.lookup(Supplier.class, name);
}
}
}
this.context = context;
}
private SpringApplicationBuilder springApplication() {
@@ -143,7 +148,7 @@ public class SpringFunctionInitializer implements Closeable {
protected Flux<?> apply(Flux<?> input) {
if (this.function != null) {
return function.apply(input);
return Flux.from(function.apply(input));
}
if (this.consumer != null) {
this.consumer.accept(input);

View File

@@ -38,21 +38,20 @@ import reactor.core.publisher.Flux;
*
*/
public class SpringFunctionInitializerTests {
private SpringFunctionInitializer initializer;
@After
public void after() {
System.clearProperty("function.name");
if (initializer!=null) {
if (initializer != null) {
initializer.close();
}
}
@Test
public void functionBean() {
initializer = new SpringFunctionInitializer(
FluxFunctionConfig.class);
initializer = new SpringFunctionInitializer(FluxFunctionConfig.class);
initializer.initialize();
Flux<?> result = initializer.apply(Flux.just(new Foo()));
assertThat(result.blockFirst()).isInstanceOf(Bar.class);
@@ -60,8 +59,7 @@ public class SpringFunctionInitializerTests {
@Test
public void functionCatalog() {
initializer = new SpringFunctionInitializer(
FunctionConfig.class);
initializer = new SpringFunctionInitializer(FunctionConfig.class);
initializer.initialize();
Flux<?> result = initializer.apply(Flux.just(new Foo()));
assertThat(result.blockFirst()).isInstanceOf(Bar.class);
@@ -69,8 +67,7 @@ public class SpringFunctionInitializerTests {
@Test
public void namedFunctionCatalog() {
initializer = new SpringFunctionInitializer(
NamedFunctionConfig.class);
initializer = new SpringFunctionInitializer(NamedFunctionConfig.class);
System.setProperty("function.name", "other");
initializer.initialize();
Flux<?> result = initializer.apply(Flux.just(new Foo()));
@@ -79,8 +76,7 @@ public class SpringFunctionInitializerTests {
@Test
public void consumerCatalog() {
initializer = new SpringFunctionInitializer(
ConsumerConfig.class);
initializer = new SpringFunctionInitializer(ConsumerConfig.class);
initializer.initialize();
Flux<?> result = initializer.apply(Flux.just(new Foo()));
assertThat(result.toStream().collect(Collectors.toList())).isEmpty();
@@ -88,8 +84,7 @@ public class SpringFunctionInitializerTests {
@Test
public void supplierCatalog() {
initializer = new SpringFunctionInitializer(
SupplierConfig.class);
initializer = new SpringFunctionInitializer(SupplierConfig.class);
initializer.initialize();
Flux<?> result = initializer.apply(Flux.empty());
assertThat(result.blockFirst()).isInstanceOf(Bar.class);