Il y a 2 semaines · 4 minutes · Back

Spring Framework 5 : tour d’horizon des nouveautés

Spring

 

Spring a sorti la première release candidate de la version 5 de son framework il y a un peu plus d’un mois.

A l’heure ou nous écrivons cet article, la version 5 de Spring est disponible en RC2. Une RC3 est prévue pour courant juillet, peu de temps avant la version finale.

Nous vous proposons par conséquent de découvrir ensemble les nouveautés et améliorations apportées à Spring Framework 5.

Passage à Java 8

Dans sa version 4, Spring était compatible avec Java 6. Avec la version 5, le code du framework a été réécrit en Java 8.

Les développeurs en ont donc profité pour :

  • Améliorer l’accès aux paramètres d’une méthode en utilisant les améliorations de la réflexivité de Java 8
  • Utiliser les méthodes par défaut des interfaces de Spring
  • Utiliser les classes Charset et StandardCharsets (disponible depuis le JDK 7)

Et dans une optique de compatibilité avec Java 9, l’instanciation des classes se fera désormais par Constructor#newInstance au lieu de Class#newInstance qui va devenir obsolète.

Spring WebFlux

Spring se met à la programmation réactive avec WebFlux dans sa version 5.

Concrètement, il s’agit de pouvoir implémenter une application web (contrôleur REST) ou des clients HTTP de manière réactive. Pour ce faire, Spring 5 intègre désormais Reactor et permet de manipuler les objets Mono (qui contient un objet) et Flux (qui peut contenir N objet(s)).

Plutôt qu’un long discours, un peu de code :

Implémentation d’un contrôleur réactive

Voici un exemple d’un contrôleur qui expose une API réactive.

@RestController
public class PersonController {

 private final PersonService service;

 public PersonController(PersonService service) {
  this.service = service;
 }

 @PostMapping("/person")
 Mono<Void> create(@RequestBody Publisher<Person> personStream) {
  return this.service.save(personStream).then();
 }

 @GetMapping("/person", produces = "text/event-stream")
 Flux<Person> list() {
  return this.service.findAll();
 }

 @GetMapping("/person/{id}")
 Mono<Person> findById(@PathVariable String id) {
  return this.service.findOne(id);
 }

Notez que la méthode list envoie des événements au consommateur du service. Ce paradigme est connu sous le nom server-sent events (SSE). Ces événements lancés par le serveur peuvent êtres consommés par des clients de différentes natures: client frontal en JavaScript, ou WebClient de Spring en Java.

Ci-dessous, l’implémentation d’un contrôleur AngularJS permettant l’utilisation d’un service web utilisant SSE grâce à l’interface EventSource :

var personModule = angular.module('persons', []);
personModule.controller('PersonsCtrl', function($scope, Persons) {
   
  $scope.init = function() {
    var source = new EventSource('/persons');
    source.onmessage = function(event) {
      $scope.$apply(function () {
        $scope.entries = JSON.parse(event.data)
      });
    };
  };
 
});

Consommer un service réactive avec Spring

Avec Spring 5, nous pouvons maintenant utiliser WebClient, une alternative non bloquante à RestTemplate qui nous permet de consommer une API REST :

WebClient client = WebClient.create("http://localhost:8080");
Mono<Account> account = client.get()
  .url("/persons/{id}", 1L)
  .accept(APPLICATION_JSON)
  .exchange(request)
  .then(response -> response.bodyToMono(Account.class));

Et pour les tests d’intégration, grâce au module spring-test, il nous est possible de facilement tester nos API grâce au WebTestClient. Une caractéristique importante de la classe WebTestClient est qu’on peut tester les points d’accès exposés par un contrôleur sans démarrer un serveur de servlets (Tomcat, Netty ou autre). Cette classe propose quelques méthodes permettant de lancer des assertions sur la réponse reçue du serveur. Voici un exemple de code :

WebTestClient client = WebTestClient
        .bindToController(new PersonController())
        .build();

client.get().uri("/persons/42")
        .exchange()
        .expectStatus().isOk()
        .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
        .expectBody(Person.class).value().isEqualTo(new Person("John"));

Bien entendu, on peut aussi se connecter une URI comme d’habitude :

WebTestClient client = WebTestClient
        .bindToServer().baseUrl("http://localhost:8080")
        .build();

client.get()...

Support avec Kotlin 1.1+

Kotlin a le vent en poupe. Et avec Spring 5, il sera possible d’utiliser le framework avec le langage de JetBrains.

Ainsi, voici comment implémenter un contrôleur REST avec Kotlin :

{
    ("/blog" and accept(TEXT_HTML)).nest {
        GET("/", fooHandler::findAllView)
        GET("/{slug}", fooHandler::findOneView)
    }
    ("/api/blog" and accept(APPLICATION_JSON)).nest {
        GET("/", this@barHandler::findAll)
        GET("/{id}", this@barHandler::findOne)
    }
}

Améliorations pour les tests

Dans sa version 5, Spring sera entièrement compatible avec les extensions de JUnit 5, en proposant SpringExtension, qui reprendra les mêmes fonctionnalités du Spring TestContext Framework.

Nous aurons aussi le droit à plusieurs nouvelles annotations :

  • @SpringJUnitConfig : équivalent à @ExtendWith(SpringExtension.class) (de JUnit 5) et @ContextConfiguration
  • @SpringJUnitWebConfig : tout comme @SpringJUnitConfig, avec en plus @WebAppConfiguration

Pour davantage d’informations, n’hésitez pas à consulter la release notes ainsi que la documentation de Spring Framework 5.

Des exemples d’utilisation de Spring 5 sont disponibles sur GitHub, que ce soit en Java et en Kotlin.

Une réflexion au sujet de « Spring Framework 5 : tour d’horizon des nouveautés »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *