Les nouveautés de Spring 3.1 présentées à Devoxx

A Devoxx, il y a une session que je ne pouvais pas manquer: les nouveautés de Spring 3.1, par Costin Leau.

En voici un résumé, avec ma propre interprétation de ses slides et mes commentaires.

Spring est aujourd’hui un framework mature, ce qui signifie que son mode de fonctionnement et ses APIs ne changent pas à chaque nouvelle version. Cependant, le framework continue à évoluer en fonction des nouvelles technologies et tendances qui arrivent: essentiellement le Cloud Computing et les nouvelles versions de Java et Jave EE dans notre cas.

Au cours des deux dernières années, nous avons ainsi vu une explosion du nombre de plateformes sur lesquels on peut déployer son application:

  • Java EE (JBoss 7, Glassfish 3, Websphere 8 )
  • Tomcat 7 avec les Servlets 3.0
  • Les platformes de Cloud: GAE (Jetty), Beanstalk (Tomcat), CloudFoundry (Tomcat), CloudBees (Tomcat)

Ces plateformes ont un certain dénominateur commun (l’API Servlet, en particulier), mais elles ont toutes des spécificités qui font qu’elles sont plus ou moins intéressantes en fonction du besoin et du moment (car ces spécificités changent avec le temps).

D’où l’importance d’être portable au niveau du déployement.

Commençons par un rappel historique: cette portabilité du déployement a toujours été le point fort de Spring: à l’origine, nous sommes nombreux à être passés à Spring car nous voulions pouvoir déployer la même application en développement (Tomcat) qu’en production (Websphere/Weblogic).

D’autre part, on a classiquement 4 environnements dans lesquels on déploie son application:

  • Le développement
  • Les tests d’intégration
  • La pré-production (“staging” en Anglais)
  • La production

Comment permettre à son application de se déployer de manière portable?

  • JNDI est la technologie d’origine, proposée par J2EE. Bien entendu, son défaut est de ne fonctionner qu’avec un container. Dans mon expérience, elle est généralement compliquée à configurer pour les équipes de production.
  • Les propriétés systèmes. C’est une solution appréciée des équipes de production, par contre en Java il nous faut un moyen d’y accéder de manière simple (ce que propose Spring).
  • Des “application contexts” Spring différents. Une solution “pure” Spring qui est très répandue.
  • Les “PlaceHolder” de Spring (avec le tag), qui est une amélioration de la méthode précédente.

Spring 3.1 vient ajouter une nouveauté: les profils de beans. On peut grouper les beans par type d’environnement cible, par exemple “dev”, “test”, “prod”.

  • Typiquement on peut avoir deux beans avec l’id “dataSource”, qui sont instanciés en fonction du profil: une dataSource de “dev” et une dataSource de “test”.
  • Cette configuration n’est pas nécessairement en XML, rappelons que Spring peut maintenant être configuré en Java (avec des annotations), ce qui permet plus de liberté dans ce cas.

Ces profils peuvent être activés via une configuration XML, ou via une API Java: il faut donc activer le bon profil au démarrage, par exemple en lisant une variable d’environnement.

Lors de la conférence, Costin a fait un sondage: la moitié des gens utilisent la configuration XML, la moitié via Java. Précisons, pour les gens qui croient encore que Spring ne se configure que par XML, que cette configuration “pure Java” est inclue dans Spring depuis 4 ans.

Cette configuration Java est généralement plus concise à utiliser pour de la configuration d’infrastructure: la définition de votre data source, de votre gestionnaire de transaction, etc… Elle est également plus puissante, car on peut plus aisément faire des branchements conditionnels ou du code spécifique qu’avec du XML.

Cette première partie de la conférence, très intéressante, a cependant un défaut: on n’y a pas rééllement parlé des nouveautés de Spring 3.1. La deuxième partie de la conférence par contre, était plus orientée sur les nouveautés de cette version 3.1.

L’abstraction du cache

Evidemment, avec l’achat de Gemfire par VMWare/SpringSource, le support du cache dans Spring est une priorité de Spring 3.1. La bonne nouvelle c’est que cette abstraction fonctionne avec plusieurs “fournisseurs” de cache, et pas que Gemfire: Ehcache (Terracotta), ConcurentMap (implémentation basique mais utile pour les tests), Redis (base NoSQL également sponsorisée par VMWare). D’autre part, des implémentations Infinispan (JBoss) et Websphere eXtreme Scale (IBM) sont en train d’être contribuées. Cette fonctionnalité est particulièrement importante pour moi:

  • La JSR Cache commence à redémarrer après des années de stagnation: c’est donc intéressant d’avoir quelque chose de déjà utilisable.
  • Dans un contexte “Cloud”, qui implique des applications multi-tenantes, avoir un cache distrbué est absolument essentiel.

Support des Servlets 3.0

Spring 3.1 va supporter l’API Servlet 3.0, avec Tomcat 7 ou GlassFish 3, tout en préservant la compatibilité Servlet 2.4.
On peut donc maintenant configurer son application Web sans fichier web.xml

Au niveau de Spring MVC, cela apporte la gestion des requêtes HTTP asynchrones. Cette fonctionnalité est particulièrement importante pour pouvoir monter en charge lorsqu’on a beaucoup de clients, et que l’on veut faire une application Web moderne, avec beaucoup d’appels Ajax (dont certains peuvent être asynchrones).

Au niveau de Spring MVC REST, un refactoring complet a été réalisé. Costin nous promet de meilleures performances, une API plus propre pour les utilisateurs avancés, tout en restant backward compatible.

A ce sujet, deux nouveautés sur l’annotation @RequestMapping sont intéressantes:

  • “consumes”, pour indiquer le type de media consumé (le “content-type header”)
  • “produces”, pour indiquer ce que l’on produit

On peut par exemple avoir la configuration suivante:
@RequestMapping(value="/foo", consumes="application/pdf")

Mises à jour de librairies

Au niveau de JPA, on peut désormais avoir le package scanning sans fichier persistence.xml, ce qui simplifie les applications avec une seule persistence unit.

Spring 3.1 va supporter nativement Hibernate 4.0, avec en particulier des packages spécifiques en fonction des versions (org.springframework.orm.hibernate3 et org.springframework.orm.hibernate4).

De même, Spring 3.1 supporte Quartz 2.x (nombreux changements dans l’API Quartz 2.0/2.1), avec compatibilité Quartz 1.5. D’où l’importance d’un système d’abstraction de la configuration, afin de pouvoir monter de version facilement.

Spring 3.1 supporte Java 7

  • Utilisation au mieux de Java 7 si il est disponible, sinon Spring utilisera Java 5 ou 6 (oui Spring 3.1 est toujours compatible Java 5)
  • Support de JDBC 4.1, en particulier pour JdbcTemplate
  • Support de la nouvelle API Fork/Join arrivée avec Java 7

Cette dernière nouveelle concerne la programmation concurrente dans le contexte actuel: nous avons en effet de plus en plus de cores sur nos machines, mais ils sont généralement moins puissants. Donc si on n’utilise pas tous ces cores de manière optimale, les performances sont moins bonnes que sur certaines “vieilles” machines.
Spring permet donc d’avoir des pools d’objets spécialisés, qui “comprennent” l’API fork/join et s’optimisent automatiquement en fonction du nombre de cores disponibles sur le serveur.
Dans un environnement “cloud” cette fonctionnalité prend tout son sens: on peut rajouter ou enlever des cores en fonction des besoins, il est donc nécessaire d’avoir une application capable de s’optimiser automatiquement en fonction de ces changements.

L’avenir et Spring 3.2

Peu d’informations sur Spring 3.2, si ce n’est que le focus sera sur les technologies suivantes:

  • Java EE 7
  • JCache (JSR 107)
  • JMS 2.0
  • Bean Validation 1.1
  • JPA 2.1
  • JSF 2.2