Spring

Maitriser les bases

Créé par Tony MEMBOT via l'API de présentation Reveal.js

Spring

  • C'est quoi spring ?
  • Spring Core
  • Spring MVC
  • Spring Security
  • Spring Batch
  • Aller plus loin avec Spring

C'est quoi Spring ?

Un conteneur léger


  • Framework reposant sur 3 grands principes
    • Inversion de contrôle
    • Programmation orientée aspect
    • Couche d'abstraction (pour d'autres API)
  • 2003 : première version
  • 2016 : 4.2.3
  • Libre

Attention aux versions !

Une version majeure = grand ménage de printemps

  • La formation se base sur les versions suivantes :
    • Spring Framework : 4.3.2.RELEASE
    • Spring Security : 4.1.3.RELEASE
    • Spring Batch : 3.0.7.RELEASE

Spring core

IoC : Inversion of Control


  • Aujourd'hui renommé injection de dépendance
  • Déresponsabilisation / Déspécialisation des classes
  • On injecte dynamiquement les dépendances plutôt que de les écrire explicitement dans le code

public class Parking {
    private Voiture voiture;

    /** Constructeur qui crée une voiture spécifique: pas d'IoC */
    public Parking() {
        voiture = new Clio();
    }

    /** Constructeur avec voiture: compatible IoC */
    public Parking(Voiture voiture) {
        this.voiture = voiture;
    }
}
                

Exemple XML

  • Dépendances maven sur spring-context
  • Un fichier xml de configuration principal
  • Déclaration de bean et d'injection de dépendance via l'xml
  • Chargement du context spring pour utilisation
  • Explorons le projet Spring 1 ...

Exemple Annotation


  • Dépendances identiques
  • Une classe de configuration principale
  • Déclaration des beans et injection de dépendance via les annotations
  • Chargement du context spring dans le main légèrement différent
  • Explorons le projet Spring 2 ...

Annotation ou XML ?

  • Pas de best solution
  • On peut quasi tout faire dans les deux solutions
  • Utiliser le meilleur des deux : un mix, exemple
    • Annotation pour tout ce qui est static
    • XML pour tout ce qui est plus dynamique
  • Mais attention, la communauté tend vers le full annotation, notamment avec Spring boot.

Déclaration d'un bean

@Component

  • Sur la classe VoitureDeCourse, va créer un bean nommé "voitureDeCourse"
  • On peut préciser ce nom @Component(value = "voiture2course")
  • @Service, @Controller, @Repository sont des spécialisations
  • On laisse spring gérer l'instanciation

@Bean

  • Disponible uniquement si on utilise @Configuration
  • Sur la méthode myVoitureDeCourse, va créer un bean nommé "myVoitureDeCourse"
  • On peut préciser ce nom @Bean(name={"voiture2course"})
  • C'est le développeur qui gère l'instanciation

@Bean factory


@Bean
@Scope("prototype")
public SomeService someService() {
    switch (state) {
        case 1:
            return new Impl1();
        case 2:
            return new Impl2();
        case 3:
            return new Impl3();
        default:
            return new Impl();
    }
}
                

Les injections de dépendances

Ou injecter ?

  • Via le fichier xml, dans la déclaration du bean
  • Par annotation, il est possible d'injecter au niveau
    • De la propriété
    • Du constructeur
    • Du setter

@Autowired

  • Injection par Type > Qualifier > Name
  • Et si on a deux implémentations de la même interface ? => Démonstration
  • Par qualifier :
    @Qualifier("name")
  • Injection par nom via le nom de l'attribut
  • Peut préciser qu'il n'est pas obligatoire
    @Autowired(required = false)
  • Annotation Spring

@Resource

  • Injection par Name > Type > Qualifier
  • Pour injecter par nom :
    @Resource(name = "name")
  • On peut lui joindre un
    @Qualifier("name")
  • Même souci sur la double implémentation que @Autowired
  • Annotation Java

@Inject

  • Fournit depuis JEE 6 par la spécification CDI.
  • Utilisé avec l'implémentation Spring, c'est l'équivalent de @autowired..
  • Injection par Type > Qualifier > Name
  • .. sauf pour la propriété required
  • Peut se compléter avec @Qualifier pour la recherche par qualifier
  • Peut se compléter avec @Named pour la recherche par nom
  • Introduction à CDI

@Resource ou @Autowired ou @Inject ?

Bin ça dépend en fait ..

Référence 1

Référence 2

Setter ou constructeur ?

On peut mixer les deux. La logique veut qu'on mette en setter les dépendances facultatives et en constructeur les obligatoires.

Le scope d'injection

  • Modifions un peu le projet Spring2 ...
  • Par défaut, tout est singleton !
  • Scopes :
    • Singleton
    • Prototype
    • Request *
    • Session *
    • GlobalSession *

Injection de collections

  • Types disponibles :
    • list
    • set
    • map
    • props
  • Tout est string dans un fichier xml ...
  • ... mais il existe des converters automatiques
  • Explorons le projet 3
  • Et l'injection d'une valeur null ?

Customiser ses beans

init-method

L'héritage / Surcharge des beans



    
    



   
   

Testons !

  1. Instancier via un new (projet 1)
  2. Compléter le projet Exo 1 ...
    • Créer les beans des voitures clio / ferrari / lotus
    • Créer deux parkings
      • Concession : avec deux clio, une ferrari, deux lotus
      • Occasion : avec deux clio, une lotus
    • Les parking initialisent les niveaux d'essence via initEssence()
    • Créer le bean garage référençant les deux parkings et le commercial
    • GarageApplication doit tourner !

Spring properties

  • Externaliser les données "changeantes" / techniques
  • Chargement de properties dans le context spring
  • Récupération des valeurs directement dans l'initialisation d'un bean ou via un @value
  • Possibilité de mettre en place un système de surcharge
  • Possibilité de mettre des valeurs par défaut

Spring Web (MVC)

MVC : un petit rappel

Spring & le web

Le dispatcher

Le dispatcher

  • Spring web tourne autour du servletdispatcher (remplace notre main)
  • Chef d'orchestre des appels HTTP et de leurs traitements

Request HTTP basique

  1. Récupération du bon controller
  2. Aiguillage (POST/GET) & préparatop, les datas
  3. Récupération de la bonne view (JSP, ...)
  4. Fusion des datas dans la view

Explorons le projet spring 5 ...

Spring EL

  • EL = Expression Language
  • Spring EL = EL au niveau injection / context spring
  • Explorons le projet spring 6 ...

Les ressources statiques

  • Si tout est résolu par le resolver .. tout est jsp ?
  • Et les js, css ?
  • Spring peut définir un context de ressources statiques
  • Exemple dans le projet spring 6 ..

Redirect & Forward

  • Toujours utile pour le pattern POST/Redirect/GET pour gérer les submit multiples
  • Redirect = retour vers le navigateur avec une réponse http 302 (redirection) vers la nouvelle url => on perd la request
  • Forward = redirection interne au serveur, transparente pour le navigateur et l'utilisateur => on conserve la request
  • Depuis la 3.1, Spring intègre les RedirectAttributes ...
    http://www.tikalk.com/redirectattributes-new-feature-spring-mvc-31/
  • Exemple dans le projet spring 7 ..

Controller - signature dynamique

  • Comment récupérer la request ? la response ? via l'injection spring
  • http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-arguments

Gestion des formulaires

Formulaire de saisie

  • Utilisation d'une taglib pour le form
  • Passage des data par un bean nommé "command" par défaut (paramétrable)
  • Le submit popule ce bean que l'on récupère dans le controller
  • Exemple dans le projet spring 8 ..

Gestion des autres input

  • Spring gère également les select, textarea, checbox, ...
  • Norme HTML => un checkbox décoché n'est pas envoyé dans le post
  • Exemple dans le projet spring 8b ..

Gestion d'un appel Ajax

  • Mapping object / data simplifié par Spring
  • Gestion de l'XML, du JSon, ...
  • Ajout des dépendances correspondantes
  • Exemple dans le projet spring 8c ..

Upload de fichier

  • Spring gère églament l'upload des fichiers
  • Quelques dépendances supplémentaires sont nécessaires
  • Exemple dans le projet spring 8d ..

Spring message / internationalisation

  • Utilisation d'un message resource : ReloadableResourceBundleMessageSource
  • Injection du bean dans les classes Java
  • Utilisation de la taglib spring:message pour les JSP
  • Internationalisation :
    • Gérer par défaut par la locale http (navigateur)
    • Gestion de priorité de la locale : application_fr_fr / application_fr / application
  • Exemple dans le projet spring 9 ..

Valider un formulaire

Pré version spring 4.X

  • Librairie externe implémentant jsr-303/jsr-349 bean validation, exemple :
  • 
        javax.validation
        validation-api
        1.0.0.ga
    
    
        org.hibernate
        hibernate-validator
        4.1.0.final
    
                            
  • Exemple complet

Valider les informations d'un formulaire

Post version 4.X

  • Spring réalise son implémentation avec @validated
  • Création de classe implémentant l'interface Validator
  • Utilisation de form:error pour remonter les erreurs
  • Exemple dans le projet Spring 10 ..

Filter encoding

  • Filtre au niveau spring
  • Permet de traiter les données HTTP dans l'encoding cible
  • Ne dispense pas de setter correctement l'encoding sur les vues

Spring security

Init

  • Gestion d'authentifications et d'autorisations
  • Brique à part entière (ne suis pas les versions)
  • Fichier de configuration à part
  • Configuration minimale pour une utilisation directe
  • Exemple dans le projet spring 11...

Personnalisation

  • Personnalisation de la page de login
  • Personnalisation des redirection logout
  • ...
  • Exemple dans le projet spring 12

Testons Spring Web !

  1. Compléter le projet Exo 2 ...
    1. GarageController doit mapper / pour renvoyer la page index.jsp
    2. Afficher le nom du commercial dans le message d'accueil
    3. Afficher les parkings
    4. Afficher les voitures dans chaque parking
    5. Mettre en place un bouton permettant d'ajouter de l'essence pour tout le parking
    6. Mettre en place un formulaire au niveau parking pour ajouter une voiture via un input
    7. Modifier ce formulaire pour prendre une liste de nom de voitures à la place de l'input

Spring Batch

Spring Batch

  • Gère des opérations récurrentes et/ou de gros volumes de données
  • Brique à part entière (ne suis pas les versions)
  • Gestion des transactions, des logs
  • Console d'administration web (start/stop/restart/skip/retry)
  • Difficile d'accès / complexe
  • Exemple dans le projet spring 13..

Spring & le test unitaire

Intégration avec JUnit

  • Spring, container léger, s'occupe d'instancier à la place de java
  • JUnit doit connaître le contexte Spring
  • Nécessite a déclaration d'un runner particulier
  • 
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {[...].class})
    @ContextConfiguration(locations = {"classpath:[...].xml"})
                        
  • Exemple dans les projets spring 14 et 15..

Spring boot

Spring boot

  • Permet la création d'une application stand alone (JAR)
  • Embarque Tomcat (default), Jetty ou Undertow
  • Configuration automatique de spring quand c'est possible
  • Aucune génération de code, aucun XML
  • Fournit des metrics par défaut
  • Exemple dans le projet spring 16..

Spring actuator

  • Ensemble de metrics par défaut
    • /health
    • /info
    • /metrics
    • /loggers
    • ...
  • Possibilité d'ajouter / surcharger
  • Attention, non accessible sans auth par défaut
  • Exemple dans le projet spring 17..

Spring boot Undertow

  • Il est possible de choisir son serveur d'application
  • Exemple dans le projet spring 17..

Customisation

  • Grande possibilité de customisation
  • Fichier de paramétrage yaml possible
  • Exemple dans le projet spring 17..

Un petit projet Todo ?

  • @PostMapping
  • Possibilité de scheduler
  • Référence : https://spring.io/guides/gs/scheduling-tasks/
  • Exemple dans le projet Spring 18..

start.spring.io

  • Génération de projet spring boot : https://start.spring.io/

De nombreux exemple

  • Spring boot est très fournit en documentation
  • https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples

Alors Spring boot ça déchire non ?

Bien ...

  • Se déploie partout juste en déponsant le jar
  • Parfait pour les micro services
  • Stack / dépendance simplifié
  • Démarrage rapide d'un nouveau projet
  • Pas de configuration xml

... mais pas parfait

  • Très compliqué à ajouter dans un projet legacy
  • Customisation parfois "lourde"
  • Pas de configuration via xml
  • Effet black box
  • On a pas forcément toute la main sur le serveur d'appli
  • Documentation fournit mais parfois brouillone

Aller plus loin avec Spring

Spring c'est aussi du ...

  • Cache (ehcache)
  • JDBC / JPA (Hibernate)
  • Mail
  • JMS
  • REST
  • AOP
  • Templating (thymeleaf)
  • ...

Spring 5

  • Release prévu en Mars 2017
  • Niveau de compatibilité drastiquement augmenté
    • Java 8+
    • Hibernate 5+
    • JPA 2.1+
    • Inclusion de spring reactive
    • Compatible kotlin

Spring 5

  • Abandon du support de nombreuses librairies :
    • PortletMVC
    • JDO
    • Guava caching
    • JasperReports
    • OpenJPA
    • Tiles 2
    • XMLBeans
    • Velocity

Plus de Spring EL

Ressources supplémentaires

  • injection list : https://www.mkyong.com/spring/spring-listfactorybean-example/
  • La bible : http://www.mkyong.com/

Merci !