SlideShare a Scribd company logo
Reactive Programming in Java and Spring 5
Richard Langlois P. Eng., Solutions Architect
January 24th, 2018
>
• Introduction to Reactive Programming
• Reactive Manifesto
• Reactive Streams Specification
• Reactor
• Reactive Programming with Spring 5
• Reactive Spring Data
Agenda
>
• Is a programming paradigm.
• Is about:
• Non-blocking applications which are
• asynchronous
• even-driven
• require a small amount of threads to scale vertically (within the JVM).
Introduction to Reactive Programming
>
From Merriam Webster: “Readily responsive to a stimulus”
• React to events (event-driven)
• React to load (scalable)
• React to failures (resilient)
• React to users (responsive)
Key to understand reactive programming is to think about it as operating on a stream of data.
Steam of data meaning a sequence of events, where an event could be
• user input (like a tap on a button),
• a response from an API request (like a Facebook feed),
• data contained in a database,
• a single variable.
Reactive
>
Reactive Manifesto is a prescription for building modern, cloud scale architecture, which is well prepared to meet the increasing
demands that applications face today.
Homepage: http://reactivemanifesto.org/
Reactive Manifesto
>
The Four Reactive Traits:
• Responsive: Application provides rich, real-time interaction with its users even under load and in the presence of failures.
• Resilient: Application recover quickly from failure (e.g. software, hardware, connections).
• Scalable: Application is able to be expanded according to its usage
• scale up: make use of more powerful hardware (aka vertical scaling)
• scale out: make use of multiple server nodes (aka horizontal scaling)
• Event-Driven: Application is composed of loosely coupled event handlers. Events can be handled asynchronously, without
blocking.
Reactive Manifesto
Characteristics
>
Reactive Streams is a Standard and specification for Stream‐oriented libraries for the JVM that
• process a potentially unbounded number of elements in sequence
• asynchronously passing elements between components
• with mandatory non‐blocking backpressure.
Specification consists of the following parts:
• The API specifies the types to implement Reactive Streams and achieve interoperability between different implementations.
• The Technology Compatibility Kit (TCK): a standard test suite for conformance testing of implementations.
Reactive Streams are only concerned with mediating the stream of data between different API Components (so operators
are not specified).
Reactive Streams specification
>
Allows to control the amount of inflight data
Regulate the transfer between:
• Slow publisher and fast consumer
• Fast publisher and slow consumer
Back Pressure (a.k.a. Flow Control)
>
Reactive Streams Specification
API
>
Those interfaces are included in Java 9 (under java.util.concurrent):
• Flow.Publisher
• Flow.Subscriber
• Flow.Subscription
• Flow.Processor
Reactive Streams Specification
Java 9
>
API Explanation:
• Communication between publisher and subscriber is set up via the publisher’s subscribe(), through which the two parties
are introduced to each other.
• After successful initialization of the communication, the subscriber gets to know about a Subscription (which models the
established connection) via a call to its onSubscribe method.
• At the core of the Reactive Streams mechanism is the request method of the Subscription. Through the request() method,
the subscriber signals to the publisher how many elements it’s ready to process.
• The publisher communicates every element one by one to the subscriber via its onNext() method, as well as fatal stream
failures through the onError() method.
• Because the publisher knows exactly how many items it’s expected to publish at any time (it has been asked for a number of
elements in the Subscription’s request method), it’s able to produce as many elements as required without producing too
many for the subscriber to consume, eliminating the need to block while waiting for the subscriber.
• Additionally, the subscriber is called by the publisher for each published element through the onNext() method, meaning
that it does not explicitly need to block while waiting for new elements to be available.
Reactive Streams Specification
>
Some Reactive Libraries on the JVM:
• RxJava: Reactive Extensions implemented on the JVM.
• Akka Streams
• Reactor Core:
Reactive Stream Specification
>
Is a fourth-generation Reactive library for building non-blocking applications on the
JVM based on the Reactive Streams Specification.
• Targets Java 8.
• Extends a Reactive Streams Publisher with the Flux and Mono API types.
It adds the concept of operators, which are chained together to describe what processing to apply at
each stage to the data.
Applying an operator returns a new intermediate Publisher.
Reactor
Core 3
>
Reactor
Evolution
>
Flux:
• A Flux<T> is a standard Publisher<T> representing an asynchronous sequence of 0 to N emitted
items, optionally terminated by either a completion signal or an error.
• Possible values of a flux: a value, a completion signal, an error.
• Translates to calls to a downstream object’s onNext, onComplete, onError methods.
• Marble diagram:
Reactor
Core Features
>
Mono:
• A Mono is a standard Publisher<T> that emits at most one item and then optionally terminates with
an onComplete signal or an onError signal.
• It offers only a subset of the operators that are available for a Flux.
• Can represent no-value asynchronous processes which have the concept of completion
(Mono<void>).
Reactor
Core Features
>
Numerous factory methods:
• Flux<String> seq1 = Flux.just("foo", "bar", "foobar");
• private static List<String> iterable = Arrays.asList ("foo", "bar", "foobar");
Flux<String> fluxFromIterable = Flux.fromIterable(iterable);
• Mono<String> noData = Mono.empty();
• Mono<String> data = Mono.just("foo");
• Flux<Integer> numbersFromFiveToSeven = Flux.range(5, 3); // 1st parameter is start of the range, 2nd is number of items
Reactor
Flux or Mono Creation
>
.subscribe variants take lambdas for different combination of callbacks:
1. subscribe(); // subscribe and trigger the sequence
2. subscribe(Consumer<? super T> consumer); // consumer run when values
3. subscribe(Consumer<? super T> consumer, // deal with values
Consumer<? super Throwable> errorConsumer); // consumer run when error
4. subscribe(Consumer<? super T> consumer, // deal with values
Consumer<? super Throwable> errorConsumer, // Consumer run when error
Runnable completeConsumer); // consumer run when sequence successfully complete
5. subscribe(Consumer<? super T> consumer, // deal with values
Consumer<? super Throwable> errorConsumer, // consumer run when error
Runnable completeConsumer, // consumer run when the sequence successfully complete
Consumer<? super Subscription> subscriptionConsumer); // consumer run when subscription produced
Reactor - Subscribe
>
Example:
// Use the subscribe() method to collect all the elements in a stream
Flux<Integer> elementsFlux = Flux.just(1, 2, 3, 4);
// subscribe with a subscriber that will print the values, The data will not start flowing until we subscribe
elementsFlux().subscribe(System.out::println(i));
Logs:
[main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | request(unbounded)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(1)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(2)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(3)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(4)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onComplete()
Reactor - Subscribe
>
Example: Tell upstream to only send 2 elements at a time by using request().
Flux.just(1, 2, 3, 4)
.log()
.subscribe(new Subscriber<Integer>() {
private Subscription s;
int onNextAmount;
@Override
public void onSubscribe(Subscription s) {
this.s = s;
s.request(2);
}
…
Reactor – Back Pressure
Example (1 of 3)
>
…
@Override
public void onNext(Integer integer) {
elements.add(integer);
onNextAmount++;
if (onNextAmount % 2 == 0) {
s.request(2);
}
}
@Override
public void onError(Throwable t) {}
@Override
public void onComplete() {}
});
Reactor – Back Pressure
Example (2 of 3)
>
Logs:
23:31:15.395 [main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription)
23:31:15.397 [main] INFO reactor.Flux.Array.1 - | request(2)
23:31:15.397 [main] INFO reactor.Flux.Array.1 - | onNext(1)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(2)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(3)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(4)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onComplete()
Notice:
The request(2) is called (when Subscribing), followed by two onNext() calls, then request(2) again, then on Complete().
Reactor – Back Pressure
Example (3 of 3)
>
Reactive Operators applies a wide range of transformations to the sequence of data (e.g. Map, Flatmap, Filter, Concat, Merge,
buffer, split, transform, delay …)
Special diagrams called Marble Diagrams efficiently explains what an operator does, for example:
Reactor - Reactive Operators
>
Map: Transform every item of the emitted sequence with a specified function.
Reactor – Reactive Operators
Map()
>
Concat:
concatenates 2 or more emissions, generating one emission where all the items from the 1st source emission appear before the
items of the 2nd source emission.
Reactor - Reactive Operators
Concat()
>
flatMap():
performs 2 types of actions:
1. the “map” action that transforms the emitted item into Flux
2. The “flatten” action that converts those Flux into one Flux.
Reactor - Reactive Operators
flatMap
>
Merge:
When we want to get feeds from multiple sources as one stream.
Reactor - Reactive Operators
merge()
>
Zip:
takes multiple observables as inputs and combines each emission via a specified function
and emits the results of this function as a new sequence.
Reactor - Reactive Operators
zip()
>
StepVerifier API:
• Builder API allowing to test how a Flux or Mono behave when subscribed to.
Some methods:
• expectNext()
• expectError()
• expectErrorMessage()
• expectComplete()
• Verify(), VerifyComplete(), VerifyError(), VerifyErrorMessage()
Reactor - Testing
StepVerifier
>
Example:
// empty Flux
Flux<String> emptyFlux = Flux.empty();
StepVerifier.create(emptyFlux).verifyComplete();
// non-empty Flux
Flux<String> nonEmptyFlux = Flux.just("John", "Mike", "Sarah");
StepVerifier.create(nonEmptyFlux).expectNext("John", "Mike", "Sarah").verify();
Call to verify():
• triggers the verification by subscribing to the Flux/Mono under test.
• Plays the sequence, comparing each new signal with the next step in the scenario
• As long as these match, the test is considered a success, else, an AssertionError is thrown.
Reactor - Testing
StepVerifier
>
• New spring-webflux module to support reactive HTTP client-side and server-side.
• Uses Reactor internally for its own reactive support.
Spring Framework 5
Reactive Support
>
Spring 5
Reactive and Servlet Stack
>
Add Dependency to pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Spring 5
WebFlux
>
• Supports 2 distinct programming models:
• Annotation-based with @Controller and the other annotations of Spring MVC
• Functional Style routing and handling with Java 8 lambda.
Spring 5
Server Side
>
Example:
@RestController
@RequestMapping(value="/api/customer")
public class RestControllerAPIs {
@GetMapping("/")
public Flux<Customer> getAll() {
...
}
@GetMapping("/{id}")
public Mono<Customer> getCustomer(@PathVariable Long id) {
...
}
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Get all customers test case:
Map<Long, Customer> custStores = new HashMap<Long, Customer>();
…
@GetMapping
public Flux<Customer> getAll() {
return Flux.fromIterable(custStores.entrySet().stream()
.map(entry -> entry.getValue())
.collect(Collectors.toList()));
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Get a customer test case:
@GetMapping("/{id}")
public Mono<Customer> getCustomer(@PathVariable Long id) {
return Mono.justOrEmpty(custStores.get(id));
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Create a customer test case:
@PostMapping("/post")
public Mono<ResponseEntity<String>> postCustomer(@RequestBody Customer customer) {
// do post
custStores.put(customer.getCustId(), customer);
return Mono.just(new ResponseEntity<>("Post Successfully!", HttpStatus.CREATED));
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Framework introduces 2 fundamental components:
• Routes a given HTTP requests via a RouterFunction (alternative to using annotations like @RequestMapping)
• Handles the request via HandlerFunction (alternative to @Controller’s handler methods).
RouterFunction utility classes are used to create RouterFunction:
e.g.
RouterFunction.route(RequestPredicate, HandlerFunction):
• helper function to create routes.
• Allows to route requests by applying a RequestPredicate.
• When the predicate is matched, then the second argument is run.
Spring 5 - WebFlux
Server Side - Functional Style
>
Example:
RouterFunction router = route( GET("/test"),
request -> ok().build() ) ;
• GET("/test") is the RequestPredicate.
• req -> ok().build() is the handler producing the response.
Spring 5
Server Side – Functional Style
>
WebClient
• Is a reactive client for performing HTTP requests with Reactive Streams back
pressure.
• Is replacing the classic RestTemplate.
• Is an interface which has a single implementation – DefaultWebClient class.
Usage(similar to HttpClient):
1. Create an instance
2. Make a request
3. Handle the reponse
Spring 5
Client side
>
Create WebClient using one of the 3 options :
• With default settings:
• WebClient client1 = WebClient.create();
• With a given base URI:
• WebClient client2 = WebClient.create("http://localhost:8080 (http://localhost:8080)");
• Using the DefaultWebClientBuilder class:
• WebClient client3 = WebClient
.builder()
.baseUrl("http://localhost:8080 (http://localhost:8080)")
.defaultCookie("cookieKey", "cookieValue")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080 (http://localhost:8080)"))
.build();
Spring 5
Client side - WebClient
>
// Setting a request body
//where a Publisher is a reactive component that is in charge of providing a potentially unbounded number of sequenced
elements.
WebClient.RequestHeadersSpec requestSpec1
= WebClient.create()
.method(HttpMethod.POST)
.uri("/resource")
.body(BodyInserters.fromPublisher(Mono.just("data")), String.class);
WebClient.RequestHeadersSpec<?> requestSpec2
= WebClient.create("http://localhost:8080 (http://localhost:8080)")
.post()
.uri(URI.create("/resource"))
.body(BodyInserters.fromObject("data"));
Spring 5
Client side - WebClient
>
A Response is obtained with exchange() or retrieve():
• exchange(): provides a ClientResponse along with its status, headers
• retrieve(): fetches a body directly
Example:
String response2 = request1.exchange()
.block()
.bodyToMono(String.class)
.block();
String response3 = request2.retrieve()
.bodyToMono(String.class)
.block();
Note: The block method on Monos is used to subscribe and retrieve an actual data which was sent with the response.
Spring 5
Client side - WebClient
>
WebTestClient
• is a non-blocking, reactive client for Spring-webflux integration testing support.
• Offers an identical API as the WebClient.
• can connect to any server over an HTTP connection.
• provides a fluent API to verify responses.
• can also bind directly to WebFlux applications with mock request and response objects.
Spring 5
Spring WebFlux Testing
>
Add Test dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
Spring 5
Spring WebFlux Testing
>
@WebFluxTest:
• auto-configures WebTestClient to quickly test WebFlux controllers without starting
a full HTTP server
Example of an unit test:
@RunWith(SpringRunner.class)
@WebFluxTest
public class SpringWebFluxTestApplicationTests {
@Autowired
private WebTestClient webTestClient;
…
}
Spring 5 - WebFlux
Testing
>
Test without starting an actual server:
WebTestClient client
= WebTestClient.bindToRouterFunction(routingFunction())
.build();
client.get().uri("/").exchange()
.expectStatus().isOk(); // Assert
Test with a real server:
WebTestClient client
= WebTestClient.bindToServer()
.baseUrl("http://localhost:8080 (http://localhost:8080)")
.build();
client.get().uri("/").exchange()
.expectStatus().isOk(); // Assert
Spring 5 - WebFlux
WebTestClient
>
Get test case:
Using WebTestClient API:
webTestClient.get().uri("/api/customer/{id}", 2).accept(MediaType.APPLICATION_JSON).exchange()
.expectStatus().isOk().expectBody(Customer.class).isEqualTo(customerMap.get("Peter")); // Assert
Using RouterFunction:
// The Router Function
RouterFunction myRouterFunction = route(GET("/test"), // RouterFunction
request -> ok().body(fromObject("hello world"))); // HandlerFunction
// Register the RouterFunction
WebTestClient webTestClient = WebTestClient.bindToRouterFunction(myRouterFunction).build();
// Assert the response
webTestClient.get().uri("/test").exchange().expectStatus().isOk();
Spring 5
WebTestClient - Example
>
POST test case:
webTestClient
// Create a POST request
.post()
.uri("/api/customer/post")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromObject(customerMap.get("Mary")))
.exchange()
// Assert the response
.expectStatus().isCreated()
.expectBody(String.class)
.isEqualTo("Post Successfully!");
Spring 5
WebTestClient - Example
>
PUT test case:
webTestClient
// Create a PUT request
.put().uri("/api/customer/put/{id}", 3)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromObject(customerMap.get("Amy")))
.exchange()
// Assert the response
.expectStatus().isCreated()
.expectBody(Customer.class)
isEqualTo(customerMap.get("Amy"));
Spring 5
WebTestClient - Example
>
DELETE test case:
webTestClient
// Create a DELETE request
.delete().uri("/api/customer/delete/{id}", 1)
.exchange()
// Assert the response
.expectStatus().isAccepted()
.expectBody(String.class)
.isEqualTo("Delete Succesfully!");
Spring 5
WebTestClient - Example
>
Spring WebFlux is supported on the following servers:
• Netty
• Undertow
• Tomcat
• Jetty
• Servlet 3.1+ containers
Spring Boot 2 uses Netty by default with WebFlux
Spring 5
Choosing a server
>
• Asynchronous
• Non Blocking
• Event Driven
• Data as stream
Reactive Data Access
>
Spring Data support Reactive Streams
Reactive Spring Data Modules:
• MongoDb
• Redis
• Cassandra
• CouchDB
Reactive Spring Data
>
Lets see an example based on Spring Data and MongoDB
Spring Data - MongoDB
>
Getting up a running Reactive Streams with Spring Data and MongoDB:
• Add the dependency (in pom.xml)
• Configuration (@EnableReactiveMongoRepositories)
• Repository interface (extends ReactiveMongoRepository, and use Flux and Mono
types)
Spring Data - MongoDB
>
Add Reactive MongoDB to our pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>http://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
Spring Data - MongoDB
Example
>
@Configuration
@EnableReactiveMongoRepositories(basePackageClasses = PersonRepository.class)
public class MongoConfig extends AbstractReactiveMongoConfiguration {
@Bean
public MongoClient mongoClient() {
return MongoClients.create();
}
@Override
protected String getDatabaseName() {
return "test";
}
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient(), getDatabaseName());
}
}
Spring Data – MongoDB
Example - Configuration
>
Configuration:
@EnableMongoRepositories enable the use of ReactiveCrudRepository.
For example:
• Mono<S> = save(S entity)
• Mono<T> = findById(ID id)
• Mono<T> = findById(Publisher<ID> id)
• Uses the first emitted element to perform the find-query
• Mono<void> = deleteById(ID id)
• Mono signaling when operation is completed
Spring Data – MongoDB
Example
>
Repository:
@EnableMongoRepositories enable the use of ReactiveCrudRepository.
public interface PersonRepository extends ReactiveMongoRepository<Person, String> {
Flux<Person> findByFirstName(final String firstName);
Mono<Person> findOneByFirstName(final String firstName);
Mono<void> = deleteById(ID id); //Mono signaling when operation is completed
}
Notice:
• Flux<Person> replaces the use of List
• Mono<Person> is used instead of Person.
This allows to perform functions on each element as they come from MongoDB database, instead of waiting until
all records are returned, and then do something with them.
Spring Data – MongoD
Example
>
Application:
@SpringBootApplication
public class Application implements CommandLineRunner {
…
@Override
public void run(String args[]) {
final Person johnAoe = new Person("john", "aoe", LocalDateTime.now(), "loser", 0);
final Person johnBoe = new Person("john", "boe", LocalDateTime.now(), "a bit of a lose
personRepository.saveAll(Flux.just(johnAoe, johnBoe)).subscribe();
personRepository.findByFirstName("john").log().map(Person::getSecondName)
.subscribe(System.out::println);
personRepository.findOneByFirstName("john").log().map(Person::getId)
.subscribe(System.out::println);
}
}
Spring Data – MongoD
Example
>
Associated Logs:
2017-07-16 16:44:09.201 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
2017-07-16 16:44:09.208 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : request(unbounded)
2017-07-16 16:44:09.242 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0))
aoe
2017-07-16 16:44:09.243 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=boe, profession=a bit of a loser,
salary=10))
boe
2017-07-16 16:44:09.247 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onComplete()
2017-07-16 16:44:09.254 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
2017-07-16 16:44:09.255 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : request(unbounded)
2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0))
596b89c97ab38934a404a80c
2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onComplete()
Spring Data – MongoD
Example
>
• The Reactive Manifesto:
• https://www.reactivemanifesto.org/
• Reactor:
• https://projectreactor.io/
• Spring WebFlux:
• https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html
• Going reactive with Spring Data:
• https://spring.io/blog/2016/11/28/going-reactive-with-spring-data
• Servlet vs Reactive Stacks in Five Use Cases:
• https://www.infoq.com/presentations/servlet-reactive-stack
References
>
Thank You!

More Related Content

What's hot (20)

Building layers of defense for your application
Building layers of defense for your applicationBuilding layers of defense for your application
Building layers of defense for your application
VMware Tanzu
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
Andres Almiray
 
Reactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...
Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...
Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...
Tin Linn Soe
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache Kafka
Shiao-An Yuan
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
Seungmo Koo
 
Introducing Swagger
Introducing SwaggerIntroducing Swagger
Introducing Swagger
Tony Tam
 
An Introduction to Maven
An Introduction to MavenAn Introduction to Maven
An Introduction to Maven
Vadym Lotar
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
Microservices with Spring 5 Webflux - jProfessionals
Microservices  with Spring 5 Webflux - jProfessionalsMicroservices  with Spring 5 Webflux - jProfessionals
Microservices with Spring 5 Webflux - jProfessionals
Trayan Iliev
 
Project Reactor By Example
Project Reactor By ExampleProject Reactor By Example
Project Reactor By Example
Denny Abraham Cheriyan
 
Spring boot jpa
Spring boot jpaSpring boot jpa
Spring boot jpa
Hamid Ghorbani
 
Introduction to Reactive programming
Introduction to Reactive programmingIntroduction to Reactive programming
Introduction to Reactive programming
Dwi Randy Herdinanto
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQL
Sangeeta Ashrit
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
Eberhard Wolff
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
Hamid Ghorbani
 
Servlet vs Reactive Stacks in 5 Use Cases
Servlet vs Reactive Stacks in 5 Use CasesServlet vs Reactive Stacks in 5 Use Cases
Servlet vs Reactive Stacks in 5 Use Cases
VMware Tanzu
 
SonarQube Presentation.pptx
SonarQube Presentation.pptxSonarQube Presentation.pptx
SonarQube Presentation.pptx
Satwik Bhupathi Raju
 
kafka
kafkakafka
kafka
Amikam Snir
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and Netty
Constantine Slisenka
 
Building layers of defense for your application
Building layers of defense for your applicationBuilding layers of defense for your application
Building layers of defense for your application
VMware Tanzu
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
Andres Almiray
 
Reactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...
Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...
Microservices Platform with Spring Boot, Spring Cloud Config, Spring Cloud Ne...
Tin Linn Soe
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache Kafka
Shiao-An Yuan
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
Seungmo Koo
 
Introducing Swagger
Introducing SwaggerIntroducing Swagger
Introducing Swagger
Tony Tam
 
An Introduction to Maven
An Introduction to MavenAn Introduction to Maven
An Introduction to Maven
Vadym Lotar
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
Microservices with Spring 5 Webflux - jProfessionals
Microservices  with Spring 5 Webflux - jProfessionalsMicroservices  with Spring 5 Webflux - jProfessionals
Microservices with Spring 5 Webflux - jProfessionals
Trayan Iliev
 
Introduction to Reactive programming
Introduction to Reactive programmingIntroduction to Reactive programming
Introduction to Reactive programming
Dwi Randy Herdinanto
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
Eberhard Wolff
 
Servlet vs Reactive Stacks in 5 Use Cases
Servlet vs Reactive Stacks in 5 Use CasesServlet vs Reactive Stacks in 5 Use Cases
Servlet vs Reactive Stacks in 5 Use Cases
VMware Tanzu
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and Netty
Constantine Slisenka
 

Similar to Reactive Programming in Java and Spring Framework 5 (20)

Reactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactorReactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactor
OrenEzer1
 
Guide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFluxGuide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFlux
Inexture Solutions
 
Reactive&amp;reactor
Reactive&amp;reactorReactive&amp;reactor
Reactive&amp;reactor
Geng-Dian Huang
 
Reactive Applications in Java
Reactive Applications in JavaReactive Applications in Java
Reactive Applications in Java
Alexander Mrynskyi
 
reactive_programming_for_java_developers.pdf
reactive_programming_for_java_developers.pdfreactive_programming_for_java_developers.pdf
reactive_programming_for_java_developers.pdf
Akshitkumar437417
 
Let’s go reactive with JAVA
Let’s go reactive with JAVALet’s go reactive with JAVA
Let’s go reactive with JAVA
Tech Triveni
 
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoSpring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Toshiaki Maki
 
Reactive mesh
Reactive meshReactive mesh
Reactive mesh
Kalin Maldzhanski
 
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Codemotion
 
Getting into the flow building applications with reactive streams
Getting into the flow building applications with reactive streamsGetting into the flow building applications with reactive streams
Getting into the flow building applications with reactive streams
Tim van Eijndhoven
 
Reactive systems
Reactive systemsReactive systems
Reactive systems
Naresh Chintalcheru
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and Reactor
Stéphane Maldini
 
From Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptxFrom Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptx
Victor Rentea
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
VMware Tanzu
 
Embracing Reactive Streams with Java 9 and Spring 5
Embracing Reactive Streams with Java 9 and Spring 5Embracing Reactive Streams with Java 9 and Spring 5
Embracing Reactive Streams with Java 9 and Spring 5
Wilder Rodrigues
 
Reactive Streams: Handling Data-Flow the Reactive Way
Reactive Streams: Handling Data-Flow the Reactive WayReactive Streams: Handling Data-Flow the Reactive Way
Reactive Streams: Handling Data-Flow the Reactive Way
Roland Kuhn
 
Workshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive StreamsWorkshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive Streams
sterkje
 
Workshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive StreamsWorkshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive Streams
Kristof Van Sever
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Codemotion
 
Reactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootReactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring Boot
VMware Tanzu
 
Reactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactorReactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactor
OrenEzer1
 
Guide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFluxGuide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFlux
Inexture Solutions
 
reactive_programming_for_java_developers.pdf
reactive_programming_for_java_developers.pdfreactive_programming_for_java_developers.pdf
reactive_programming_for_java_developers.pdf
Akshitkumar437417
 
Let’s go reactive with JAVA
Let’s go reactive with JAVALet’s go reactive with JAVA
Let’s go reactive with JAVA
Tech Triveni
 
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoSpring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Toshiaki Maki
 
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Codemotion
 
Getting into the flow building applications with reactive streams
Getting into the flow building applications with reactive streamsGetting into the flow building applications with reactive streams
Getting into the flow building applications with reactive streams
Tim van Eijndhoven
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and Reactor
Stéphane Maldini
 
From Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptxFrom Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptx
Victor Rentea
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
VMware Tanzu
 
Embracing Reactive Streams with Java 9 and Spring 5
Embracing Reactive Streams with Java 9 and Spring 5Embracing Reactive Streams with Java 9 and Spring 5
Embracing Reactive Streams with Java 9 and Spring 5
Wilder Rodrigues
 
Reactive Streams: Handling Data-Flow the Reactive Way
Reactive Streams: Handling Data-Flow the Reactive WayReactive Streams: Handling Data-Flow the Reactive Way
Reactive Streams: Handling Data-Flow the Reactive Way
Roland Kuhn
 
Workshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive StreamsWorkshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive Streams
sterkje
 
Workshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive StreamsWorkshop: Event-sourced system through Reactive Streams
Workshop: Event-sourced system through Reactive Streams
Kristof Van Sever
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Codemotion
 
Reactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootReactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring Boot
VMware Tanzu
 
Ad

More from Richard Langlois P. Eng. (7)

Monitoring with Prometheus
Monitoring with PrometheusMonitoring with Prometheus
Monitoring with Prometheus
Richard Langlois P. Eng.
 
Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.
Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.
Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.
Richard Langlois P. Eng.
 
Microservice Architecture Patterns, by Richard Langlois P. Eng.
Microservice Architecture Patterns, by Richard Langlois P. Eng.Microservice Architecture Patterns, by Richard Langlois P. Eng.
Microservice Architecture Patterns, by Richard Langlois P. Eng.
Richard Langlois P. Eng.
 
What's New in Java 9
What's New in Java 9What's New in Java 9
What's New in Java 9
Richard Langlois P. Eng.
 
DevOps, Yet Another IT Revolution
DevOps, Yet Another IT RevolutionDevOps, Yet Another IT Revolution
DevOps, Yet Another IT Revolution
Richard Langlois P. Eng.
 
What is new in JUnit5
What is new in JUnit5What is new in JUnit5
What is new in JUnit5
Richard Langlois P. Eng.
 
Introduction to Reactive Microservices Architecture.
Introduction to Reactive Microservices Architecture.Introduction to Reactive Microservices Architecture.
Introduction to Reactive Microservices Architecture.
Richard Langlois P. Eng.
 
Ad

Recently uploaded (20)

Micro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Micro-Metrics Every Performance Engineer Should Validate Before Sign-OffMicro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Micro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Tier1 app
 
Agile Software Engineering Methodologies
Agile Software Engineering MethodologiesAgile Software Engineering Methodologies
Agile Software Engineering Methodologies
Gaurav Sharma
 
Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...
Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...
Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...
WSO2
 
Automating Map Production With FME and Python
Automating Map Production With FME and PythonAutomating Map Production With FME and Python
Automating Map Production With FME and Python
Safe Software
 
Content Mate Web App Triples Content Managers‘ Productivity
Content Mate Web App Triples Content Managers‘ ProductivityContent Mate Web App Triples Content Managers‘ Productivity
Content Mate Web App Triples Content Managers‘ Productivity
Alex Vladimirovich
 
FME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable InsightsFME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable Insights
Safe Software
 
Bonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdfBonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdf
Herond Labs
 
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The SequelMarketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
BradBedford3
 
Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...
Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...
Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...
SheenBrisals
 
Topic 26 Security Testing Considerations.pptx
Topic 26 Security Testing Considerations.pptxTopic 26 Security Testing Considerations.pptx
Topic 26 Security Testing Considerations.pptx
marutnand8
 
Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3
Gaurav Sharma
 
How John started to like TDD (instead of hating it) (ViennaJUG, June'25)
How John started to like TDD (instead of hating it) (ViennaJUG, June'25)How John started to like TDD (instead of hating it) (ViennaJUG, June'25)
How John started to like TDD (instead of hating it) (ViennaJUG, June'25)
Nacho Cougil
 
14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework
Angelo Theodorou
 
Essentials of Resource Planning in a Downturn
Essentials of Resource Planning in a DownturnEssentials of Resource Planning in a Downturn
Essentials of Resource Planning in a Downturn
OnePlan Solutions
 
zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17
zOSCommserver
 
Simplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for ContractorsSimplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for Contractors
SHEQ Network Limited
 
AI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATION
AI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATIONAI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATION
AI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATION
miso_uam
 
Key AI Technologies Used by Indian Artificial Intelligence Companies
Key AI Technologies Used by Indian Artificial Intelligence CompaniesKey AI Technologies Used by Indian Artificial Intelligence Companies
Key AI Technologies Used by Indian Artificial Intelligence Companies
Mypcot Infotech
 
The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...
Prachi Desai
 
COBOL Programming with VSCode - IBM Certificate
COBOL Programming with VSCode - IBM CertificateCOBOL Programming with VSCode - IBM Certificate
COBOL Programming with VSCode - IBM Certificate
VICTOR MAESTRE RAMIREZ
 
Micro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Micro-Metrics Every Performance Engineer Should Validate Before Sign-OffMicro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Micro-Metrics Every Performance Engineer Should Validate Before Sign-Off
Tier1 app
 
Agile Software Engineering Methodologies
Agile Software Engineering MethodologiesAgile Software Engineering Methodologies
Agile Software Engineering Methodologies
Gaurav Sharma
 
Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...
Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...
Build Smarter, Deliver Faster with Choreo - An AI Native Internal Developer P...
WSO2
 
Automating Map Production With FME and Python
Automating Map Production With FME and PythonAutomating Map Production With FME and Python
Automating Map Production With FME and Python
Safe Software
 
Content Mate Web App Triples Content Managers‘ Productivity
Content Mate Web App Triples Content Managers‘ ProductivityContent Mate Web App Triples Content Managers‘ Productivity
Content Mate Web App Triples Content Managers‘ Productivity
Alex Vladimirovich
 
FME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable InsightsFME for Climate Data: Turning Big Data into Actionable Insights
FME for Climate Data: Turning Big Data into Actionable Insights
Safe Software
 
Bonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdfBonk coin airdrop_ Everything You Need to Know.pdf
Bonk coin airdrop_ Everything You Need to Know.pdf
Herond Labs
 
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The SequelMarketo & Dynamics can be Most Excellent to Each Other – The Sequel
Marketo & Dynamics can be Most Excellent to Each Other – The Sequel
BradBedford3
 
Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...
Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...
Eliminate the complexities of Event-Driven Architecture with Domain-Driven De...
SheenBrisals
 
Topic 26 Security Testing Considerations.pptx
Topic 26 Security Testing Considerations.pptxTopic 26 Security Testing Considerations.pptx
Topic 26 Security Testing Considerations.pptx
marutnand8
 
Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3Software Engineering Process, Notation & Tools Introduction - Part 3
Software Engineering Process, Notation & Tools Introduction - Part 3
Gaurav Sharma
 
How John started to like TDD (instead of hating it) (ViennaJUG, June'25)
How John started to like TDD (instead of hating it) (ViennaJUG, June'25)How John started to like TDD (instead of hating it) (ViennaJUG, June'25)
How John started to like TDD (instead of hating it) (ViennaJUG, June'25)
Nacho Cougil
 
14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework14 Years of Developing nCine - An Open Source 2D Game Framework
14 Years of Developing nCine - An Open Source 2D Game Framework
Angelo Theodorou
 
Essentials of Resource Planning in a Downturn
Essentials of Resource Planning in a DownturnEssentials of Resource Planning in a Downturn
Essentials of Resource Planning in a Downturn
OnePlan Solutions
 
zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17zOS CommServer support for the Network Express feature on z17
zOS CommServer support for the Network Express feature on z17
zOSCommserver
 
Simplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for ContractorsSimplify Training with an Online Induction Portal for Contractors
Simplify Training with an Online Induction Portal for Contractors
SHEQ Network Limited
 
AI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATION
AI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATIONAI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATION
AI-ASSISTED METAMORPHIC TESTING FOR DOMAIN-SPECIFIC MODELLING AND SIMULATION
miso_uam
 
Key AI Technologies Used by Indian Artificial Intelligence Companies
Key AI Technologies Used by Indian Artificial Intelligence CompaniesKey AI Technologies Used by Indian Artificial Intelligence Companies
Key AI Technologies Used by Indian Artificial Intelligence Companies
Mypcot Infotech
 
The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...The rise of e-commerce has redefined how retailers operate—and reconciliation...
The rise of e-commerce has redefined how retailers operate—and reconciliation...
Prachi Desai
 
COBOL Programming with VSCode - IBM Certificate
COBOL Programming with VSCode - IBM CertificateCOBOL Programming with VSCode - IBM Certificate
COBOL Programming with VSCode - IBM Certificate
VICTOR MAESTRE RAMIREZ
 

Reactive Programming in Java and Spring Framework 5

  • 1. Reactive Programming in Java and Spring 5 Richard Langlois P. Eng., Solutions Architect January 24th, 2018
  • 2. > • Introduction to Reactive Programming • Reactive Manifesto • Reactive Streams Specification • Reactor • Reactive Programming with Spring 5 • Reactive Spring Data Agenda
  • 3. > • Is a programming paradigm. • Is about: • Non-blocking applications which are • asynchronous • even-driven • require a small amount of threads to scale vertically (within the JVM). Introduction to Reactive Programming
  • 4. > From Merriam Webster: “Readily responsive to a stimulus” • React to events (event-driven) • React to load (scalable) • React to failures (resilient) • React to users (responsive) Key to understand reactive programming is to think about it as operating on a stream of data. Steam of data meaning a sequence of events, where an event could be • user input (like a tap on a button), • a response from an API request (like a Facebook feed), • data contained in a database, • a single variable. Reactive
  • 5. > Reactive Manifesto is a prescription for building modern, cloud scale architecture, which is well prepared to meet the increasing demands that applications face today. Homepage: http://reactivemanifesto.org/ Reactive Manifesto
  • 6. > The Four Reactive Traits: • Responsive: Application provides rich, real-time interaction with its users even under load and in the presence of failures. • Resilient: Application recover quickly from failure (e.g. software, hardware, connections). • Scalable: Application is able to be expanded according to its usage • scale up: make use of more powerful hardware (aka vertical scaling) • scale out: make use of multiple server nodes (aka horizontal scaling) • Event-Driven: Application is composed of loosely coupled event handlers. Events can be handled asynchronously, without blocking. Reactive Manifesto Characteristics
  • 7. > Reactive Streams is a Standard and specification for Stream‐oriented libraries for the JVM that • process a potentially unbounded number of elements in sequence • asynchronously passing elements between components • with mandatory non‐blocking backpressure. Specification consists of the following parts: • The API specifies the types to implement Reactive Streams and achieve interoperability between different implementations. • The Technology Compatibility Kit (TCK): a standard test suite for conformance testing of implementations. Reactive Streams are only concerned with mediating the stream of data between different API Components (so operators are not specified). Reactive Streams specification
  • 8. > Allows to control the amount of inflight data Regulate the transfer between: • Slow publisher and fast consumer • Fast publisher and slow consumer Back Pressure (a.k.a. Flow Control)
  • 10. > Those interfaces are included in Java 9 (under java.util.concurrent): • Flow.Publisher • Flow.Subscriber • Flow.Subscription • Flow.Processor Reactive Streams Specification Java 9
  • 11. > API Explanation: • Communication between publisher and subscriber is set up via the publisher’s subscribe(), through which the two parties are introduced to each other. • After successful initialization of the communication, the subscriber gets to know about a Subscription (which models the established connection) via a call to its onSubscribe method. • At the core of the Reactive Streams mechanism is the request method of the Subscription. Through the request() method, the subscriber signals to the publisher how many elements it’s ready to process. • The publisher communicates every element one by one to the subscriber via its onNext() method, as well as fatal stream failures through the onError() method. • Because the publisher knows exactly how many items it’s expected to publish at any time (it has been asked for a number of elements in the Subscription’s request method), it’s able to produce as many elements as required without producing too many for the subscriber to consume, eliminating the need to block while waiting for the subscriber. • Additionally, the subscriber is called by the publisher for each published element through the onNext() method, meaning that it does not explicitly need to block while waiting for new elements to be available. Reactive Streams Specification
  • 12. > Some Reactive Libraries on the JVM: • RxJava: Reactive Extensions implemented on the JVM. • Akka Streams • Reactor Core: Reactive Stream Specification
  • 13. > Is a fourth-generation Reactive library for building non-blocking applications on the JVM based on the Reactive Streams Specification. • Targets Java 8. • Extends a Reactive Streams Publisher with the Flux and Mono API types. It adds the concept of operators, which are chained together to describe what processing to apply at each stage to the data. Applying an operator returns a new intermediate Publisher. Reactor Core 3
  • 15. > Flux: • A Flux<T> is a standard Publisher<T> representing an asynchronous sequence of 0 to N emitted items, optionally terminated by either a completion signal or an error. • Possible values of a flux: a value, a completion signal, an error. • Translates to calls to a downstream object’s onNext, onComplete, onError methods. • Marble diagram: Reactor Core Features
  • 16. > Mono: • A Mono is a standard Publisher<T> that emits at most one item and then optionally terminates with an onComplete signal or an onError signal. • It offers only a subset of the operators that are available for a Flux. • Can represent no-value asynchronous processes which have the concept of completion (Mono<void>). Reactor Core Features
  • 17. > Numerous factory methods: • Flux<String> seq1 = Flux.just("foo", "bar", "foobar"); • private static List<String> iterable = Arrays.asList ("foo", "bar", "foobar"); Flux<String> fluxFromIterable = Flux.fromIterable(iterable); • Mono<String> noData = Mono.empty(); • Mono<String> data = Mono.just("foo"); • Flux<Integer> numbersFromFiveToSeven = Flux.range(5, 3); // 1st parameter is start of the range, 2nd is number of items Reactor Flux or Mono Creation
  • 18. > .subscribe variants take lambdas for different combination of callbacks: 1. subscribe(); // subscribe and trigger the sequence 2. subscribe(Consumer<? super T> consumer); // consumer run when values 3. subscribe(Consumer<? super T> consumer, // deal with values Consumer<? super Throwable> errorConsumer); // consumer run when error 4. subscribe(Consumer<? super T> consumer, // deal with values Consumer<? super Throwable> errorConsumer, // Consumer run when error Runnable completeConsumer); // consumer run when sequence successfully complete 5. subscribe(Consumer<? super T> consumer, // deal with values Consumer<? super Throwable> errorConsumer, // consumer run when error Runnable completeConsumer, // consumer run when the sequence successfully complete Consumer<? super Subscription> subscriptionConsumer); // consumer run when subscription produced Reactor - Subscribe
  • 19. > Example: // Use the subscribe() method to collect all the elements in a stream Flux<Integer> elementsFlux = Flux.just(1, 2, 3, 4); // subscribe with a subscriber that will print the values, The data will not start flowing until we subscribe elementsFlux().subscribe(System.out::println(i)); Logs: [main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | request(unbounded) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(1) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(2) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(3) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(4) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onComplete() Reactor - Subscribe
  • 20. > Example: Tell upstream to only send 2 elements at a time by using request(). Flux.just(1, 2, 3, 4) .log() .subscribe(new Subscriber<Integer>() { private Subscription s; int onNextAmount; @Override public void onSubscribe(Subscription s) { this.s = s; s.request(2); } … Reactor – Back Pressure Example (1 of 3)
  • 21. > … @Override public void onNext(Integer integer) { elements.add(integer); onNextAmount++; if (onNextAmount % 2 == 0) { s.request(2); } } @Override public void onError(Throwable t) {} @Override public void onComplete() {} }); Reactor – Back Pressure Example (2 of 3)
  • 22. > Logs: 23:31:15.395 [main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription) 23:31:15.397 [main] INFO reactor.Flux.Array.1 - | request(2) 23:31:15.397 [main] INFO reactor.Flux.Array.1 - | onNext(1) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(2) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(3) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(4) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onComplete() Notice: The request(2) is called (when Subscribing), followed by two onNext() calls, then request(2) again, then on Complete(). Reactor – Back Pressure Example (3 of 3)
  • 23. > Reactive Operators applies a wide range of transformations to the sequence of data (e.g. Map, Flatmap, Filter, Concat, Merge, buffer, split, transform, delay …) Special diagrams called Marble Diagrams efficiently explains what an operator does, for example: Reactor - Reactive Operators
  • 24. > Map: Transform every item of the emitted sequence with a specified function. Reactor – Reactive Operators Map()
  • 25. > Concat: concatenates 2 or more emissions, generating one emission where all the items from the 1st source emission appear before the items of the 2nd source emission. Reactor - Reactive Operators Concat()
  • 26. > flatMap(): performs 2 types of actions: 1. the “map” action that transforms the emitted item into Flux 2. The “flatten” action that converts those Flux into one Flux. Reactor - Reactive Operators flatMap
  • 27. > Merge: When we want to get feeds from multiple sources as one stream. Reactor - Reactive Operators merge()
  • 28. > Zip: takes multiple observables as inputs and combines each emission via a specified function and emits the results of this function as a new sequence. Reactor - Reactive Operators zip()
  • 29. > StepVerifier API: • Builder API allowing to test how a Flux or Mono behave when subscribed to. Some methods: • expectNext() • expectError() • expectErrorMessage() • expectComplete() • Verify(), VerifyComplete(), VerifyError(), VerifyErrorMessage() Reactor - Testing StepVerifier
  • 30. > Example: // empty Flux Flux<String> emptyFlux = Flux.empty(); StepVerifier.create(emptyFlux).verifyComplete(); // non-empty Flux Flux<String> nonEmptyFlux = Flux.just("John", "Mike", "Sarah"); StepVerifier.create(nonEmptyFlux).expectNext("John", "Mike", "Sarah").verify(); Call to verify(): • triggers the verification by subscribing to the Flux/Mono under test. • Plays the sequence, comparing each new signal with the next step in the scenario • As long as these match, the test is considered a success, else, an AssertionError is thrown. Reactor - Testing StepVerifier
  • 31. > • New spring-webflux module to support reactive HTTP client-side and server-side. • Uses Reactor internally for its own reactive support. Spring Framework 5 Reactive Support
  • 32. > Spring 5 Reactive and Servlet Stack
  • 33. > Add Dependency to pom.xml: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> Spring 5 WebFlux
  • 34. > • Supports 2 distinct programming models: • Annotation-based with @Controller and the other annotations of Spring MVC • Functional Style routing and handling with Java 8 lambda. Spring 5 Server Side
  • 35. > Example: @RestController @RequestMapping(value="/api/customer") public class RestControllerAPIs { @GetMapping("/") public Flux<Customer> getAll() { ... } @GetMapping("/{id}") public Mono<Customer> getCustomer(@PathVariable Long id) { ... } } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 36. > Get all customers test case: Map<Long, Customer> custStores = new HashMap<Long, Customer>(); … @GetMapping public Flux<Customer> getAll() { return Flux.fromIterable(custStores.entrySet().stream() .map(entry -> entry.getValue()) .collect(Collectors.toList())); } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 37. > Get a customer test case: @GetMapping("/{id}") public Mono<Customer> getCustomer(@PathVariable Long id) { return Mono.justOrEmpty(custStores.get(id)); } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 38. > Create a customer test case: @PostMapping("/post") public Mono<ResponseEntity<String>> postCustomer(@RequestBody Customer customer) { // do post custStores.put(customer.getCustId(), customer); return Mono.just(new ResponseEntity<>("Post Successfully!", HttpStatus.CREATED)); } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 39. > Framework introduces 2 fundamental components: • Routes a given HTTP requests via a RouterFunction (alternative to using annotations like @RequestMapping) • Handles the request via HandlerFunction (alternative to @Controller’s handler methods). RouterFunction utility classes are used to create RouterFunction: e.g. RouterFunction.route(RequestPredicate, HandlerFunction): • helper function to create routes. • Allows to route requests by applying a RequestPredicate. • When the predicate is matched, then the second argument is run. Spring 5 - WebFlux Server Side - Functional Style
  • 40. > Example: RouterFunction router = route( GET("/test"), request -> ok().build() ) ; • GET("/test") is the RequestPredicate. • req -> ok().build() is the handler producing the response. Spring 5 Server Side – Functional Style
  • 41. > WebClient • Is a reactive client for performing HTTP requests with Reactive Streams back pressure. • Is replacing the classic RestTemplate. • Is an interface which has a single implementation – DefaultWebClient class. Usage(similar to HttpClient): 1. Create an instance 2. Make a request 3. Handle the reponse Spring 5 Client side
  • 42. > Create WebClient using one of the 3 options : • With default settings: • WebClient client1 = WebClient.create(); • With a given base URI: • WebClient client2 = WebClient.create("http://localhost:8080 (http://localhost:8080)"); • Using the DefaultWebClientBuilder class: • WebClient client3 = WebClient .builder() .baseUrl("http://localhost:8080 (http://localhost:8080)") .defaultCookie("cookieKey", "cookieValue") .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080 (http://localhost:8080)")) .build(); Spring 5 Client side - WebClient
  • 43. > // Setting a request body //where a Publisher is a reactive component that is in charge of providing a potentially unbounded number of sequenced elements. WebClient.RequestHeadersSpec requestSpec1 = WebClient.create() .method(HttpMethod.POST) .uri("/resource") .body(BodyInserters.fromPublisher(Mono.just("data")), String.class); WebClient.RequestHeadersSpec<?> requestSpec2 = WebClient.create("http://localhost:8080 (http://localhost:8080)") .post() .uri(URI.create("/resource")) .body(BodyInserters.fromObject("data")); Spring 5 Client side - WebClient
  • 44. > A Response is obtained with exchange() or retrieve(): • exchange(): provides a ClientResponse along with its status, headers • retrieve(): fetches a body directly Example: String response2 = request1.exchange() .block() .bodyToMono(String.class) .block(); String response3 = request2.retrieve() .bodyToMono(String.class) .block(); Note: The block method on Monos is used to subscribe and retrieve an actual data which was sent with the response. Spring 5 Client side - WebClient
  • 45. > WebTestClient • is a non-blocking, reactive client for Spring-webflux integration testing support. • Offers an identical API as the WebClient. • can connect to any server over an HTTP connection. • provides a fluent API to verify responses. • can also bind directly to WebFlux applications with mock request and response objects. Spring 5 Spring WebFlux Testing
  • 47. > @WebFluxTest: • auto-configures WebTestClient to quickly test WebFlux controllers without starting a full HTTP server Example of an unit test: @RunWith(SpringRunner.class) @WebFluxTest public class SpringWebFluxTestApplicationTests { @Autowired private WebTestClient webTestClient; … } Spring 5 - WebFlux Testing
  • 48. > Test without starting an actual server: WebTestClient client = WebTestClient.bindToRouterFunction(routingFunction()) .build(); client.get().uri("/").exchange() .expectStatus().isOk(); // Assert Test with a real server: WebTestClient client = WebTestClient.bindToServer() .baseUrl("http://localhost:8080 (http://localhost:8080)") .build(); client.get().uri("/").exchange() .expectStatus().isOk(); // Assert Spring 5 - WebFlux WebTestClient
  • 49. > Get test case: Using WebTestClient API: webTestClient.get().uri("/api/customer/{id}", 2).accept(MediaType.APPLICATION_JSON).exchange() .expectStatus().isOk().expectBody(Customer.class).isEqualTo(customerMap.get("Peter")); // Assert Using RouterFunction: // The Router Function RouterFunction myRouterFunction = route(GET("/test"), // RouterFunction request -> ok().body(fromObject("hello world"))); // HandlerFunction // Register the RouterFunction WebTestClient webTestClient = WebTestClient.bindToRouterFunction(myRouterFunction).build(); // Assert the response webTestClient.get().uri("/test").exchange().expectStatus().isOk(); Spring 5 WebTestClient - Example
  • 50. > POST test case: webTestClient // Create a POST request .post() .uri("/api/customer/post") .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromObject(customerMap.get("Mary"))) .exchange() // Assert the response .expectStatus().isCreated() .expectBody(String.class) .isEqualTo("Post Successfully!"); Spring 5 WebTestClient - Example
  • 51. > PUT test case: webTestClient // Create a PUT request .put().uri("/api/customer/put/{id}", 3) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromObject(customerMap.get("Amy"))) .exchange() // Assert the response .expectStatus().isCreated() .expectBody(Customer.class) isEqualTo(customerMap.get("Amy")); Spring 5 WebTestClient - Example
  • 52. > DELETE test case: webTestClient // Create a DELETE request .delete().uri("/api/customer/delete/{id}", 1) .exchange() // Assert the response .expectStatus().isAccepted() .expectBody(String.class) .isEqualTo("Delete Succesfully!"); Spring 5 WebTestClient - Example
  • 53. > Spring WebFlux is supported on the following servers: • Netty • Undertow • Tomcat • Jetty • Servlet 3.1+ containers Spring Boot 2 uses Netty by default with WebFlux Spring 5 Choosing a server
  • 54. > • Asynchronous • Non Blocking • Event Driven • Data as stream Reactive Data Access
  • 55. > Spring Data support Reactive Streams Reactive Spring Data Modules: • MongoDb • Redis • Cassandra • CouchDB Reactive Spring Data
  • 56. > Lets see an example based on Spring Data and MongoDB Spring Data - MongoDB
  • 57. > Getting up a running Reactive Streams with Spring Data and MongoDB: • Add the dependency (in pom.xml) • Configuration (@EnableReactiveMongoRepositories) • Repository interface (extends ReactiveMongoRepository, and use Flux and Mono types) Spring Data - MongoDB
  • 58. > Add Reactive MongoDB to our pom.xml: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.BUILD-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> </dependency> </dependencies> <repositories> <repository> <id>spring-libs-snapshot</id> <name>Spring Snapshot Repository</name> <url>http://repo.spring.io/libs-snapshot</url> </repository> </repositories> Spring Data - MongoDB Example
  • 59. > @Configuration @EnableReactiveMongoRepositories(basePackageClasses = PersonRepository.class) public class MongoConfig extends AbstractReactiveMongoConfiguration { @Bean public MongoClient mongoClient() { return MongoClients.create(); } @Override protected String getDatabaseName() { return "test"; } @Bean public ReactiveMongoTemplate reactiveMongoTemplate() { return new ReactiveMongoTemplate(mongoClient(), getDatabaseName()); } } Spring Data – MongoDB Example - Configuration
  • 60. > Configuration: @EnableMongoRepositories enable the use of ReactiveCrudRepository. For example: • Mono<S> = save(S entity) • Mono<T> = findById(ID id) • Mono<T> = findById(Publisher<ID> id) • Uses the first emitted element to perform the find-query • Mono<void> = deleteById(ID id) • Mono signaling when operation is completed Spring Data – MongoDB Example
  • 61. > Repository: @EnableMongoRepositories enable the use of ReactiveCrudRepository. public interface PersonRepository extends ReactiveMongoRepository<Person, String> { Flux<Person> findByFirstName(final String firstName); Mono<Person> findOneByFirstName(final String firstName); Mono<void> = deleteById(ID id); //Mono signaling when operation is completed } Notice: • Flux<Person> replaces the use of List • Mono<Person> is used instead of Person. This allows to perform functions on each element as they come from MongoDB database, instead of waiting until all records are returned, and then do something with them. Spring Data – MongoD Example
  • 62. > Application: @SpringBootApplication public class Application implements CommandLineRunner { … @Override public void run(String args[]) { final Person johnAoe = new Person("john", "aoe", LocalDateTime.now(), "loser", 0); final Person johnBoe = new Person("john", "boe", LocalDateTime.now(), "a bit of a lose personRepository.saveAll(Flux.just(johnAoe, johnBoe)).subscribe(); personRepository.findByFirstName("john").log().map(Person::getSecondName) .subscribe(System.out::println); personRepository.findOneByFirstName("john").log().map(Person::getId) .subscribe(System.out::println); } } Spring Data – MongoD Example
  • 63. > Associated Logs: 2017-07-16 16:44:09.201 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : onSubscribe(FluxOnErrorResume.ResumeSubscriber) 2017-07-16 16:44:09.208 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : request(unbounded) 2017-07-16 16:44:09.242 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0)) aoe 2017-07-16 16:44:09.243 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=boe, profession=a bit of a loser, salary=10)) boe 2017-07-16 16:44:09.247 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onComplete() 2017-07-16 16:44:09.254 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : onSubscribe(FluxOnErrorResume.ResumeSubscriber) 2017-07-16 16:44:09.255 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : request(unbounded) 2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0)) 596b89c97ab38934a404a80c 2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onComplete() Spring Data – MongoD Example
  • 64. > • The Reactive Manifesto: • https://www.reactivemanifesto.org/ • Reactor: • https://projectreactor.io/ • Spring WebFlux: • https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html • Going reactive with Spring Data: • https://spring.io/blog/2016/11/28/going-reactive-with-spring-data • Servlet vs Reactive Stacks in Five Use Cases: • https://www.infoq.com/presentations/servlet-reactive-stack References