Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Going Reactive with Spring 5

189 views

Published on

In recent times, Reactive Programming has gained a lot of popularity. It is not a “silver bullet” nor it is a solution for every problem. Yet, it is a paradigm to build applications which are non-blocking, event-driven and asynchronous and require a small number of threads to scale. Spring Framework 5 embraces Reactive Streams and Reactor for its own reactive use, as well as in many of its core APIs. It also adds an ability to code in a declarative way, as opposed to imperatively, resulting in more responsive and resilient applications. On top of that, you are given an amazing toolbox of functions to combine, create and filter any data stream. It becomes easy to support input and output streaming scenarios for microservices, scatter/gather, data ingestion, and so on. This presentation is about support and building blocks for reactive programming, that come with the latest versions of Spring Framework 5 and Spring Boot 2.

Published in: Technology
  • Be the first to comment

Going Reactive with Spring 5

  1. 1. Going Reactive with Spring 5 #jPrime2018
  2. 2. Who am I? Java Technical Lead at Seavus 17 years in the industry Spring Certified Professional You can find me at: ● drazen.nikolic@seavus.com ● @drazenis ● programminghints.com
  3. 3. Changing Requirements (then and now) 10 years ago Now Server nodes 10’s 1000’s Response times seconds milliseconds Maintenance downtimes hours none Data volume GBs TBs → PBs
  4. 4. Solution? EASY: Just spin up more threads!
  5. 5. Reactive Programming Event-driven systems Moves imperative logic to: ● asynchronous ● non-blocking ● functional-style code Allows stable, scalable access to external systems Example use-cases: Monitoring stock prices Streaming videos Spreadsheets Fraud detection
  6. 6. When to Use Reactive? ● Handling networking issues, like latency or failures ● Scalability concerns ● Clients getting overwhelmed by the sent messages (handling backpressure) ● Highly concurrent operations
  7. 7. Reactive Manifesto www.reactivemanifesto.org
  8. 8. Reactive Streams Specification ● A spec based on Reactive Manifesto prescription ● Intention to scale vertically (within JVM), rather then horizontally (through clustering) ● A standard for async data stream processing ● Non-blocking flow control (backpressure) ● The Exceptions are first-class citizens
  9. 9. Reactive Streams Specification public interface Publisher<T> { public void subscribe(Subscriber<? super T> s); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscription { public void request(long n); public void cancel(); } public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {}
  10. 10. How it works? Reactive Streams Implementations for Java: RxJava Project Reactor Akka Streams Ratpack Vert.x 3
  11. 11. Spring Framework 5 Another major release, became GA in September 2017 A lots of improvements and new concepts introduced: ● Support for JDK 9 ● Support Java EE 8 API (e.g. Servlet 4.0) ● Integration with Project Reactor 3.1 ● JUnit 5 ● Comprehensive support for Kotlin language ● Dedicated reactive web framework - Spring WebFlux
  12. 12. Project Reactor: Mono<T> Publisher which emits 0 or 1 element (successfully or with an error)
  13. 13. Project Reactor: Flux<T> Publisher which emits 0 to N elements (successfully or with an error)
  14. 14. Various Reactor Operators
  15. 15. Various Reactor Operators
  16. 16. Various Reactor Operators
  17. 17. Reactor Pipeline ● Lazy evaluated ● Nothing is produced until there is a subscriber userService.getFavorites(userId) .timeout(Duration.ofMillis(800)) .onErrorResume(cacheService.cachedFavoritesFor(userId)) .flatMap(favoriteService::getDetails) .switchIfEmpty(suggestionService.getSuggestions()) .take(5) .publishOn(UiUtils.uiThreadScheduler()) .subscribe(uiList::show, UiUtils::errorPopup);
  18. 18. Spring 5 Reactive Web
  19. 19. Annotation-based Programming Model @RestController public class PersonController { private final PersonRepository repository; public PersonController(PersonRepository repository) { this.repository = repository; } @GetMapping("/person") Flux<Person> list() { return this.repository.findAll(); } @GetMapping("/person/{id}") Mono<Person> findById(@PathVariable String id) { return this.repository.findOne(id); } }
  20. 20. Functional Programming Model - Handler public class PersonHandler { ... public Mono<ServerResponse> listPeople(ServerRequest request) { Flux<Person> people = repository.allPeople(); return ServerResponse.ok().contentType(APPLICATION_JSON) .body(people, Person.class); } public Mono<ServerResponse> createPerson(ServerRequest request) { Mono<Person> person = request.bodyToMono(Person.class); return ServerResponse.ok().build(repository.savePerson(person)); } }
  21. 21. Functional Programming Model - Router PersonRepository repository = ... PersonHandler handler = new PersonHandler(repository); RouterFunction<ServerResponse> personRoute = route(GET("/person/{id}").and(accept(APPLICATION_JSON)), handler::getPerson) .andRoute(GET("/person").and(accept(APPLICATION_JSON)), handler::listPeople) .andRoute(POST("/person").and(contentType(APPLICATION_JSON)), handler::createPerson);
  22. 22. Functional Reactive Client WebClient client = WebClient.create("http://example.com"); Mono<Account> account = client.get() .url("/accounts/{id}", 1L) .accept(APPLICATION_JSON) .exchange(request) .then(response -> response.bodyToMono(Account.class));
  23. 23. Functional Reactive WebSocket Client WebSocketClient webSocketClient = new ReactorNettyWebSocketClient(); webSocketClient.execute(new URI("wss://echo.websocket.org"), session -> session.send(input.map(session::textMessage)) .thenMany(session .receive() .map(WebSocketMessage::getPayloadAsText) .log()) .then())
  24. 24. Spring Data Reactive public interface BookRepository extends ReactiveCrudRepository<Book, String> { Flux<Book> findByAuthor(String author); } <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> </dependency>
  25. 25. WebFlux Spring Security @EnableWebFluxSecurity public class HelloWebfluxSecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("user") .roles("USER") .build(); return new MapReactiveUserDetailsService(user); } }
  26. 26. Reactive Method Security @EnableWebFluxSecurity @EnableReactiveMethodSecurity public class SecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsService() {...} } @Component public class HelloWorldMessageService { @PreAuthorize("hasRole('ADMIN')") public Mono<String> findMessage() { return Mono.just("Hello World!"); } }
  27. 27. DEMO https://github.com/drazen-nikolic/reactive-spring-5-demo
  28. 28. Questions?
  29. 29. References & Attributions Reactive Streams Specification for the JVM Reactive Spring - Josh Long, Mark Heckler Reactive Programming by Venkat Subramaniam What is Reactive Programming by Martin Oderski Reactive Streams: Handling Data-Flow the Reactive Way by Roland Kuhn What Are Reactive Streams in Java? by John Thompson Spring Boot Reactive Tutorial by Mohit Sinha Doing Reactive Programming with Spring 5 by Eugen Paraschiv
  30. 30. Be proactive, go Reactive! Spring will help you on this journey! Thank you Where applicable...

×