Reactive Programming ist in der Enterprise-Java-Welt angekommen. Frameworks wie Akka und RxJava waren Vorreiter, mit WebFlux und Project Reactor in Spring 5 ist ein weiteres prominentes Framework dazugekommen. Aber was steckt eigentlich hinter Reactive Programming? Wann ergibt der Einsatz Sinn und wie kann ich es in bestehende Anwendungen integrieren? Die Session gibt eine Einführung in das Programmiermodell, zeigt die Umsetzung in den verschiedenen Projekten, diskutiert, wann Reactive Programming Sinn ergibt, und liefert einen Ausblick, welche Themen im Bereich Reactive Programming in Zukunft kommen.
33. Reactive Enterprise Java | Arne Limburg
Java 9 Flow API
public interface Flow.Publisher<T>;
public interface Flow.Subscriber<T>;
public interface Flow.Processor<T, R>;
public interface Flow.Subscription;
34. Reactive Enterprise Java | Arne Limburg
Java 9 Flow API
public interface Flow.Publisher<T> {
void subscribe(Flow.Subscriber<? super T> subscriber);
}
35. Reactive Enterprise Java | Arne Limburg
Java 9 Flow API
public interface Flow.Subscriber<T> {
void onSubscribe(Flow.Subscription subscription);
void onNext(T item);
void onError(Throwable error);
void onComplete();
}
36. Reactive Enterprise Java | Arne Limburg
Java 9 Flow API
public interface Flow.Subscription {
void request(long n);
void cancel();
}
37. Reactive Enterprise Java | Arne Limburg
Java 9 Flow API
public interface Flow.Processor<T, R>
extends Flow.Subscriber<T>, Flow.Publisher<R> {
}
38. Reactive Enterprise Java | Arne Limburg
Reactive mit Spring Webflux
@GetMapping("/orders/{orderNo}/status")
public Mono<OrderStatus> getStatus(@PathVariable("orderNo") number) {
return WebClient
.create("https://…payment-service…")
.get()
.accept(APPLICATION_JSON)
.retrieve()
.toMono(PaymentStatus.class)
.map(OrderStatus::fromPaymentStatus);
}
39. Reactive Enterprise Java | Arne Limburg
Logging & Debugging?
@GetMapping("/orders/{orderNo}/status")
public Mono<OrderStatus> getStatus(@PathVariable("orderNo") number) {
Hooks.onOperatorDebug();
return WebClient
.create("https://…payment-service…")
.get()
.accept(APPLICATION_JSON)
.retrieve()
.toMono(PaymentStatus.class)
.log()
.checkpoint() // alternative to Hooks.onOperatorDebug()
.map(OrderStatus::fromPaymentStatus);
}
42. Reactive Enterprise Java | Arne Limburg
Kombinierter Status mit Project Reactor
Mono<OrderStatus> orderStatus
= Mono.zip(
WebClient.create("https://…payment-service…").get()
.accept(APPLICATION_JSON).retrieve().toMono(PaymentStatus.class),
WebClient.create("https://…stock-service…").get()
.accept(APPLICATION_JSON).retrieve().toMono(StockStatus.class),
WebClient.create("https://…shipping-service…").get()
.accept(APPLICATION_JSON).retrieve().toMono(ShippingStatus.class))
.map(this::toOrderStatus);
43. Reactive Enterprise Java | Arne Limburg
Reactive mit Spring Webflux
@GetMapping("/orders")
public Flux<CustomerOrder> getOrders() {
return orderRepository.findAll();
}
50. Reactive Enterprise Java | Arne Limburg
Async & Await in Javascript
const orderIds = await connection
.execute("SELECT orderId FROM CustomerOrder ");
async function execute(sql) {
return new Promise(…);
}
51. Reactive Enterprise Java | Arne Limburg
Blockierender Thread in Java
ResultSet result = statement
.executeQuery("SELECT orderId FROM CustomerOrder");
while (result.next()) {
…
}
52.
53. Reactive Enterprise Java | Arne Limburg
Reactive Database Access mit R2DBC
Publisher<OrderItem> items = client.execute()
.sql("SELECT ITEM_ID, ITEM_NAME FROM TAB_ORDER_ITEM")
.fetch()
.all();
items.subscribe(rowProcessor);
54.
55.
56. Reactive Enterprise Java | Arne Limburg
Blockierender Thread in Java
ResultSet result
= statement
.executeQuery("SELECT orderId FROM CustomerOrder");
while (result.next()) {
…
}
59. KONTAKT
Reactive Enterprise Java | Arne Limburg
ARNE LIMBURG
ENTERPRISE ARCHITECT
arne.limburg@openknowledge.de
+49 (0)441 4082 – 0
Icons in this presentation designed by “Freepik”, “Nice and Serious” and “Elegant Themes” from www.flaticon.com
OFFENKUNDIGGUT