Spring – Formation au Framework couteau suisse – C'est quoi Spring ?



Spring – Formation au Framework couteau suisse – C'est quoi Spring ?

0 0


formationSpring

formation sur spring core et dérivé

On Github reivon / formationSpring

Spring

Formation au Framework couteau suisse

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

Se présenter. Leur domaine / niveau struts/spring/MVC/... Pas formation expert. Il faut fouiller/adapter.

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
Conteneur léger : brique de base pour instancier des objets et les mettre en relation. Pour faire plus, on rajoute des briques. Tomcat = conteneur léger, jboss conteneur lourd Inversion de contrôle = Injection de dépendance. (exemple par la suite) Définir programmation orienté aspect => transversale. Couche d'abstraction : Hibernate / quartz / velocity / jdbc / ... Entre chaque version il y a eu de nombreuses et importantes évolution.

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
évoluer est nécessaire. C'est une force de spring

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;
    }
}
                
Parking a ici la responsabilité de l'instanciation de la Clio. Ca ne peut être que ça. Si l'application évolue, ou on souhaite l'étendre, ou on souhaite mocker pour test => on doit modifier le code.

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 ...
Projet exemple : springFormation_1. Dépendance de context : https://mvnrepository.com/artifact/org.springframework/spring-context/4.3.2.RELEASE app / beans / core / expression. Il est possible de découper le fichier XML en réalisant des imports (Mais un seul point d'entrée).

                

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 ...
Projet exemple : springFormation_2. On peut retrouver l'annotation @Bean aussi Ainsi, si dans messageServiceImpl on supprime le @Component, on peut déclarer dans la classe Application:
                    @Bean
                    public MessageServiceImpl messageService(){
                        return new MessageServiceImpl();
                    }
                    
Il est à noter que l'on peut avoir plusieurs @Configuration si on souhaite découper notre application. On peut réaliser des héritages / dépendances avec @Import(nomClass.class)

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

@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
@Service, ... sont des spécialisations dans le but d'utiliser l'AOP.

@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
Attention, on ne peut plus utiliser l'AOP sur des instanciations de type @Bean. => http://zezutom.blogspot.fr/2014/02/spring-series-part-5-component-vs-bean.html @Autowired peut injecter un @Bean

@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();
    }
}
                
Ce cas peut être utile pour du mock par exemple, ou pour instancier des classes différentes selon un environnement ... La différence entre les deux est ténue. On préfera garder @Component généralement.

Les injections de dépendances

@Autowired

  • Injection par type
  • Et si on a deux implémentations de la même interface ? => Démonstration
  • Avec @Qualifier("name") : injection par nom
  • Peut préciser qu'il n'est pas obligatoire @Autowired(required = false)
  • Annotation Spring
Démonstration : 1. Créer une classe MessageServiceAutreImpl qui implémente MessageService 2. Lancer l'appli. => plante. pas obligatoire = ne plante pas.

@Resource

  • Injection par type
  • Même souci sur la double implémentation que @Component
  • Pour injecter par nom :
    @Resource(name = "name")
  • Annotation Java
@Resource(name = "toto")
private Toto toto;
                

==

@Autowired
@Qualifier("toto")
private Toto toto;
                

@Resource ou @Autowired ?

Sur des injections de propriétés, il est préférable d'utiliser @Resource qui est un standard Java et qui est fait pour ça.

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 *
Faire un test sur formationSpring_2 en ajoutant un 2ème service dans MessagePrinter. Puis ajouter dans l'appel d'affichage System.out.println(service2.getMessage()); service2.setMessage("message modifié"); System.out.println(service.getMessage()); System.out.println(service2.getMessage()); * = que dans spring web. Ajouter => @Scope("prototype")

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 ?
Exemple avec le projet spring 3. L'utilité de tout ça ? notamment pour injecter des listes de beans / référence. Injecter null ? "" représentant une chaîne vide ?

Customiser ses beans

init-method



                
                    Modifier le projet 1 pour ajouter une init method à messageserviceimpl qui changerait le message par exemple.
                

L'héritage / Surcharge des beans



                
                    On peut rendre un bean abstract="true" sans définir de class (sera pas instancié par Spring)
                    http://www.tutorialspoint.com/spring/spring_bean_definition_inheritance.htm
                

Testons !

Instancier via un new (projet 1) 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 !
1. L'objet est hors contexte, pas d'initialisation de variable etc. erreur courante au début ! 2. voiture ne doit pas être instancié, les voitures = prototype Montrer exemple spEL

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
exemple du projet 4. pour utiliser la variable, déclarer dans les arguments vm : -Dproject.home=c:/ rajouter une valeur par défaut : :c:/conf/

Spring Web (MVC)

MVC : un petit rappel

découpage de responsabilité ...

Spring & le web

spring mvc est une spécialisation de spring qui donne des outils pour gérer des pages 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

Récupération du bon controller Aiguillage (POST/GET) & préparatop, les datas Récupération de la bonne view (JSP, ...) Fusion des datas dans la view 1. Après l'avoir reçu, DispatcherServlet consulte HandlerMapping pour appelerle bon Controller. 2. Le Controller gère la request et appel la bonne méthode (GET / POST) et prépare les objets qui vont alimentés le model ainsi que le nom du modèle. 3. Le DispatcherServlet utilise le ViewResolver pour récupérer la bonne view. 4. Le DispatcherServlet fusione les datas avec la view et retourne le résultat.

Explorons le projet spring 5 ...

lancer l'appli et accéder à http://localhost:8080/hello (si lancer depuis intellij) web.xml => dispatcher servlet hellocontroller => @controller @requestmapping hello-servlet => spring recherche automatiquement le fichier {{nomservlet}}-servlet.xml => on peut lui préciser d'autres noms dans le web.xml => contient la ligne de scan pour les controller => contient un résolver permettant de rediriger vers nos ressources jsp. => le resolver peut implémenter des framework de view comme tiles / velocity / ...v

Spring EL

  • EL = Expression Language
  • Spring EL = EL au niveau injection / context spring
  • Explorons le projet spring 6 ...
localhost:8080/hello & localhost:8080/hello/toto spring-el est déjà en dépendance de webmvc dépendance : ne pas oublier d'ajouter javax.servlet attention à la vieille erreur que les paramètres ne s'affichent pas sur les jsp https://www.mkyong.com/spring-mvc/modelandviews-model-value-is-not-displayed-in-jsp-via-el/ (web.xml) el ne marche pas :

(web.xml) el marche :

                

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 ..
Exemple de spring 6 : localhost:8080/index On a ajouté dans le servlet.xml mvc:resources ... mvc:annotation-driven ... Et dans hello.jsp ajout des références et utilisation de taglib.

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 ..
exemple du projet 7 : localhost:8080/index RedirectAttributes = flash attribute = marche pour 1 seul redirect. F5 et tout disparaît => http://www.tikalk.com/redirectattributes-new-feature-spring-mvc-31/

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
Exemple projet 7 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-arguments HttpServletResponse response TimeZone timezone

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 ..
exemple du projet formationspring_8 : objet "command" = bean (attention aux setter / getter) nom du bean paramétrable

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 ..
Des valeurs par défaut ont été mises en place.

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 ..
Ajouts dépendances jackson Appel JQuery Ajax. Mapping automatique. Attention de bien produire du JSON (on peut renseigner le produce dans le requestmapping)

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 ..
Ajout dépendances commons-fileupload & commons-io AJout enctype="multipart/form-data" dans le formulaire Remarque, ce n'est pas un champ form:file

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 ..
exemple du projet formationspring_9 on a ajouté un resolver ainsi qu'un interceptor, via l'url on peut changer la locale. http://localhost:8080/student http://localhost:8080/student?locale=en De manière native c'est géré par le accept language de la requête http. Fichiers externe à l'application ? file:/usr/local/conf/app/messages/messages

Valider un formulaire

Pré version spring 4.X

  • Librairie externe implémentant jsr-303/jsr-349 bean validation, exemple :
  • javax.validationvalidation-api1.0.0.gaorg.hibernatehibernate-validator4.1.0.final
  • Exemple complet
C'est classique et bien détaillé, voyons plutôt la solution spring.

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 ..
                    http://www.mkyong.com/spring-mvc/spring-mvc-form-handling-example/
                    Projet Spring 10 = Spring 8 + validation.
                        on rajoute l'email pour montrer les dépendances de validator.
                        Ajout de deux validator
                        Ajout du tag form:error dans la jsp du formulaire
                        Modification du controller pour déclencher le validator
                        détail sur le messageressource => on a plusieurs fichiers de messageresource maintenant.
                            note : il y a un ordre d'application. le dernier prend le pas sur les suivant.
                            permet de faire du fallback. on charge d'abord le fichier dans l'appli puis un externe par exemple.

                    Attention ! dans le controller, l'attribut bindingresult result doit obligatoirement être placé juste après le modelattribute à valider.
                    sinon erreur 400 ! c'est le seul paramètre qui a une place conditionné au niveau des controlleurs spring.
                    => http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-methods
                    

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
Exemple dans le projet 10

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...
web.xml on ajoute le filtre de spring security dans le web.xml on crée le fichier de configuration de spring security test d'accès : localhost:8080/welcome localhost:8080/admin la login page est par défaut spring 4 demande de gérer des tokens crslf

Personnalisation

  • Personnalisation de la page de login
  • Personnalisation des redirection logout
  • ...
  • Exemple dans le projet spring 12
ajout d'une page de login déclaration controller login ajout page login le logout est géré par login?logout automatiquement l'erreur de log est géré par login?error automatiquement username et password doivent être présent

Testons Spring Web !

Compléter le projet Exo 2 ... GarageController doit mapper / pour renvoyer la page index.jsp Afficher le nom du commercial dans le message d'accueil Afficher les parkings Afficher les voitures dans chaque parking Mettre en place un bouton permettant d'ajouter de l'essence pour tout le parking Mettre en place un formulaire au niveau parking pour ajouter une voiture via un input 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 batch donne des notions communes à tous les jobs : job step itemwriter ... http://projects.spring.io/spring-batch/ http://www.mkyong.com/tutorials/spring-batch-tutorial/ http://blog.netapsys.fr/spring-batch-par-lexemple-2/

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
spring reactive => Programmation réactive = programmation avec des flux de données asynchrones http://home.heeere.com/tech-intro-programmation-reactive.html

Spring 5

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

Plus de Spring EL

  • "#{ T(java.lang.Math).random() * 100.0 }"
  • "#{ systemProperties['user.region'] }"
  • http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-beandef
  • http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-ref-functions
  • https://www.mkyong.com/spring3/spring-el-hello-world-example/
  • https://www.mkyong.com/spring3/spring-el-lists-maps-example/
Converter date : https://www.mkyong.com/spring/spring-how-to-pass-a-date-into-bean-property-customdateeditor/ Converter bean & mvc : https://www.javacodegeeks.com/2013/11/type-conversion-in-spring-2.html

Ressources

  • inject, resource, autowired : http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/
  • injection list : https://www.mkyong.com/spring/spring-listfactorybean-example/
  • La bible : http://www.mkyong.com/

Merci !

Spring Formation au Framework couteau suisse Créé par Tony MEMBOT via l'API de présentation Reveal.js Se présenter. Leur domaine / niveau struts/spring/MVC/... Pas formation expert. Il faut fouiller/adapter.