GMIN30F Réutilisation / Composants

publicité
GMIN30F
Réutilisation / Composants
Intervenant : André Morassut
Informations légales
Ce document est la propriété exclusive de Berger-Levrault, toute
reproduction même partielle est interdite sans l’autorisation
écrite des services idoines de Berger-Levrault.
Le logo Berger-Levrault est la propriété exclusive de BergerLevrault S.A.
Les autres images de cette présentation sont issues de
commons.wikimedia.org
Structure
1. Contexte industriel

Le contexte « industriel »



la perception des notions
Convergences et motifs : réutilisabilité et composants
Un cas d’expérience : le CORE WEB2
2. Réutilisation et composants – En pratique


Réutilisation « passive » et « active »
Composants internes et externes
3. Pratiques actuelles

Présentation d’outils représentatifs de l’outillage actuel favorisé par les
éditeurs de logiciel
SECONDE PARTIE
Projet de développement
– Réalisation d’un projet JAVA EE+MAVEN+SPRING
– Serveur REST sur base JPA
– Grandes étapes de mise en place :
• Partie 1 :
–
–
–
–
Mise en place du projet
Branchement de MAVEN
Mise en place de SPRING
Définition d’un service REST « helloworld »
• Partie 2 :
– Mise en place de JPA
– Création des entités métier + DAO + services
– Branchement des services REST
Travaux de programmation
Partie 1 - Webapplication
Partie 1 - Webapplication
– Focus sur les briques manipulées :
• MAVEN : voir partie 1 du cours
• SPRING : « boîte à outils » en lien avec JAVA EE
• REST : approche architecturale consistant en une
ensemble coordonné de contraintes sur l’utilisation
d’abstractions (structuration des informations,
composants, connecteurs, …) de l’architecture du
« world wide web »
• Serveur JAVA EE : Serveur WEB intégrant des logiques
de traitement des cycles de vie d’aspects normés JAVA
EE.
SPRING
SPRING
– Synthétiquement, SPRING présente des
alternatives et des implémentations de normes
JAVA EE
– SPRING présente de multiple facettes :
•
•
•
•
•
IoC (Injection de dépendances)
JPA & transactions : DsL, helpers, etc.
Web application : lifecycle, servlets, etc.
Security
Autres:
– NoSQL, Social, Cloud, Batch processing, LDAP, Mobile, etc.
REST
REST
– REST = REpresentational State Transfer
– Créé en 2000, REST s’impose largement en entreprise ces
dernières années
– REST apporte:
•
•
•
•
Un ensemble de contraintes architecturales
Une approche d’abstraction
Une ouverture technologique
Une forte orientation composant
– Pour ces raisons REST est particulièrement adapté à une
vision architecturale modulaire
 Voyons les contraintes en détail
REST – Contraintes (1/4)
– Contraintes architecturales:
•
•
•
•
Client/serveur
Sans état (Stateless)
Cachable
Système en couches
– Approche d’abstraction Implémentation WWW :
•
•
•
•
Utilisation des « verbes » HTTP
Utilisation d’un format de données ouvert : JSON, XML
Utilisation des URI
Utilisation des Hyperliens
REST – Contraintes (2/4)
– Ouverture technologique
• REST peut être implémenté dans toutes les technologies
permettant des composantes sous-jacentes (http, json, xml, etc.)
• Les notions à implémenter :
– Ressource = élément d’une API REST, c’est une opération unitaire
– Représentation = donnée structurée représentant une notion
manipulée par une interface REST, en entrée ou sortie
– Message = communication client vers serveur ou inversement,
pouvant contenir une ou plusieurs représentations par exemple
– « Hypermedia state » = opérations disponibles sur un serveur REST à
un instant donné
REST – Contraintes (3/4)
– Orientation composant : REST propose une uniformisation
des interfaces (contrats) autour de certaines contraintes
• Identification des ressources & séparation
ressource/représentation
Chaque ressource est identifiable par requête (utilisation des URI
dans une implémentation www) et les représentations manipulées
sont conceptuellement séparée des ressources (ainsi, un serveur
peut retourner une information en JSON ou XML, celle-ci sera une
projection de la représentation interne du serveur qui peut être
éventuellement plus riche.)
• Les représentations permettent la manipulation des ressources
 Les représentations retournées par un serveur en réponse à une
requête sont suffisantes à un client donné pour qu’il puisse
modifier ou supprimer les éléments correspondants
REST – Contraintes (4/4)
– Orientation composant : REST propose une uniformisation
des interfaces (contrats) autour de certaines contraintes
• Messages auto descriptifs
Chaque message contient les informations suffisantes pour
permettre à un client de savoir comment les traiter. En pratique,
c’est l’inclusions d’informations comme : encodage (utf-8, etc.),
structuration (xml, json, etc.), gestion de la mise en cache, etc.
• HATEOAS : « hypermedia as the engine of application state »
 Une API REST présentée par un serveur peut être vue comme une
machine à état. Un client peut uniquement déclencher des
transitions d’états à travers les opérations mises à disposition à un
instant donné par le serveur.
Serveur JAVA EE
Serveur JAVA EE
– Un serveur JAVA EE (ex: Glassfish, JBOSS AS, etc.) est un
serveur d’application implémentant un ensemble de
normes JAVA EE.
– À travers un système de certification, ORACLE estampille
un serveur comme « JAVA EE » s’il implémente
correctement un ensemble de normes jugées
indispensables
– Quelques serveurs JAVA EE:
• EE 7 : Glassfish 4, RedHat WildFly 8, …
• EE 6 : JBOSS AS7, Apache Geronimo 3, Glassfish 3,
Websphere 8, …
Serveur JAVA EE
– Un serveur JAVA EE propose typiquement plusieurs
moyens de configuration
• Console dédiée
• JMX connectors
– Un serveur JAVA EE permet la gestion des versions des
modules qu’il intègre, indépendamment des applications
– Nous verrons l’intérêt d’un serveur d’application à travers
la gestion de deux aspects :
• Injection de dépendances
• Gestion des transactions
Travaux de programmation
Partie 2 - Webapplication
Partie 2 - Webapplication
– Focus sur les notions & briques manipulées :
• Modalités architecturales JAVA EE
– Applications en couche
– DAO & « Active record »
• En lien avec les serveurs d’application
– Inversion de contrôle : détail de cette notion
– Gestion des transactions : détail de cette notion
• JPA : norme JAVA EE de gestion de la persistance
• Aspects connexes : logging, Unit tests
Modalités architecturales
diapo 21
Modalités architecturales
• Les architectures autour de JAVA EE convergent
autour de quelques point essentiels
– Approche en couche
• Séparation des responsabilités
• Entités métiers & services essentiellement
– Stateless (versus stateful)
– Approche de persistance
• Par DAO
• Par « active record »
diapo 22
Modalités architecturales
Détaillons les deux approches de gestion de l’isolation du code de
persistance:
- Approche « Data Access Object »
- Les DAO sont des objets dédiés à la gestion de la persistance
- Les objets métiers n’ont aucune « intelligence métier », ce sont de
simple conteneurs de données
- Les DAO intègrent une partie de l’intelligence métier (une couche
service est souvent employée pour séparer l’orchestration de la
persistance)
- Généralement, on met en place un objet DAO par objet métier avec
extension d’une super classe regroupant les implémentations par
défaut
diapo 23
Modalités architecturales
Détaillons les deux approches de gestion de l’isolation du code de
persistance:
- Approche « Active Record »
- Contrairement à l’approche DAO, le code de persistance est intégré
aux objets métier
- Les objets métiers contiennent l’intelligence du métier
- Parfois, une couche service est mise en place pour des raisons
d’orchestration.
- Par exemple, on peut avoir besoin de coordonner des objets Personne, Adresse,
Ville, etc. pour réaliser une fonctionnalité métier d’enregistrement d’une nouvelle
personne.
diapo 24
Architecture Web, Active record
JAVA EE Container ou Spring
Client
SGBDs
Oracle / sql server / …
diapo 25
Objets métier
Hibernate
(Service)
Architecture Web, approche DAO
JAVA EE Container ou Spring
Client
Service
DAO
Objets métier
diapo 26
SGBDs
Oracle / sql server / …
Hibernate
Modalités architecturales
Comparons les deux approches de gestion de l’isolation du code de
persistance:
- Approche « Data Access Object »
Avantages
Inconvénients
-Séparation des responsabilités
- Permet de factoriser du code par la
superclasse de DAO
- Simplification des tests par « mock » ou
« bouchonnage »
- Permet de remplacer une
implémentation de manière ciblée
- Adapté à des projets de taille
importante
-Le coût réel des appels en base de
données est masqué
- Prolifération des DAO si le nombre des
entités métier est élevé
- Il faut être vigilant pour ne pas
introduire des aspects métiers dans les
DAO
 L’approche DAO est particulièrement adaptée aux domaines métiers
multi-sujets.
diapoétendus,
27
-
Modalités architecturales
Comparons les deux approches de gestion de l’isolation du code de
persistance:
- Approche « Active record »
Avantages
Inconvénients
-Simplicité
-Réduction du nombre de classes
- Cohérent avec l’approche objet : les
entités métiers ne sont pas de simples
conteneurs de donnée
- le domaine métier est peu malléable :
si un objet donné doit être utilisé dans
plusieurs contextes différents, son code
s’en trouvera très complexifié
- lourdeur des refactorings
-Difficultés pour les tests
 L’approche Active record est intéressante quand le domaine métier est
réduit et traite d’un objectif unique
diapo 28
Modalités architecturales
Ces deux approches sont très généralement mises en place de
manière STATELESS. Ainsi, les services ne conservent aucun
état et ne connaissent pas les sessions de travail des clients.
Cela implique que chaque opération exposée par le serveur
doit :
- permettre d’aller d’un état cohérent du domaine métier à un
autre état cohérent
- ne pas requérir d’être orchestrée dans un ordre particulier
 En réalité, l’aspect STATELESS de l’architecture rapproche l’API
exposée par le serveur aux clients de REST.
diapo 29
JAVA EE - Transactions & IOC
Injection de dépendances (1/8)
 IoC signifie « Inversion of Control »
 L’inversion de contrôle est permise par l’injection de
dépendances
 Principe de l’inversion des dépendances, permet :
– Suivre les évolutions techniques tout en épargnant le code
métier
– Réflexion sur couplage fort versus couplage faible par
interfaces.
 Un bon design objet est plus important que les
technologies sous-jacentes.
 Tout code doit être facilement testable.
diapo 31
Différentes dépendances (2/8)
diapo 32
A
B
A
<< I >>
A
B
A utilise B
A implémente une interface I
A hérite de B
IOC - Conséquences (3/8)
• Les dépendances ne permettent pas :
– D’installer A sans installer B
• Donc de réutiliser A sans réutiliser B
– Une modification de B
• Peut entraîner une modification de A
• Une recompilation de A
– Il y a perte de réutilisation et de modularité
A
diapo 33
B
IOC - Conséquences (4/8)
• Objectifs : Eviter
– Rigidité
• Application difficile à modifier car chaque changement affecte
d'autres parties du logiciel
– Fragilité
• Une modification entraîne des effets de bords : BUG
– Immobilité
• Difficulté de reprendre une partie de l'application car elle ne
peut pas être indépendante des autres parties
A
diapo 34
B
IOC - Direction (5/8)
Classe A
Classe B
Classe A
ou
 Peut-on choisir le sens d’une dépendance ?
diapo 35
Classe B
Inversion de dépendances (6/8)
Situation de départ
Classe A
Classe B
Ajout d’une interface
Classe A
Interface I
Classe B
implémente
diapo 36
Injection de dépendance (7/8)
 Problématique initiale :
– pouvoir remplacer l’implémentation utilisée par un composant de manière
simple
– L’injection a pour base la notion d’interface : le composant « utilisateur » se
base sur un « contrat »
 Pattern :
ClasseA
ClasseB
IClasseB
implémente
setIClasseA()
Cible de l’injection
diapo 37
Injection de dépendances (8/8)
– Dans le cadre d’un serveur d’application :
• Via un conteneur JAVA EE (serveur JAVA EE), nous allons pouvoir
laisser celui-ci gérer les injections
• Ainsi, selon la charge, les éléments de paramétrage, etc. le serveur
va décider d’instancier, réutiliser, mettre en cache, etc. les
ressources déclarées en injection
• D’autres ressources peuvent être injectées :
– Data sources
– Règles de sécurité
– Etc.
• Les serveurs peuvent être configurés pour fonctionner en
coopération : gestion de la charge, réplications, etc.
 Un tel serveur représente une composante importante d’une architecture
industrielle, rendant des services qui sont de fait découplés des applications
métier (séparation des responsabilités)
Gestion des transactions
Notion de transaction :
Une transaction permet d’associer un ensemble
d’opérations dans une session de travail.
Si les exécutions de toutes les opérations se
terminent correctement la transaction aboutie
Si une des opérations ne se termine pas
correctement, la transaction échoue
Un exemple
• La réservation d’un billet de spectacle
4 opérations OK
Réserver billet
1- Consultation des places disponibles
2- Réservation de la place
3- Réception du paiement
4- Émission du ticket de réservation
1 opération KO
diapo 40
Propriétés ACID (1/2)
• Propriétés fondamentales d’une transaction
 Atomic (Atomicité)
 Les opérations qui constituent une transaction forment une unité indivisible :
soit l’ensemble des opérations est mené à terme, soit aucune opération n’est
effectuée.
 Consistent (Cohérence)
 La base passe d’un état initial cohérent à un état final cohérent, dans le respect
des règles d’intégrités référentielles définies sur la base de données.
diapo 41
Propriétés ACID (2/2)
 Isolated (Isolation)
 Les mises à jour effectuées au cours de l’exécution d’une transaction
restent invisibles aux autres transactions.
 Durable (Durabilité)
 Le résultat de la transaction est persisté dans le système, même après
l’arrêt de celui-ci.
diapo 42
JPA, Spring & transactions
 Les EJBs (Enterprise Java Bean), comme SPRING,
apportent un support pour les transactions
programmatiques et déclaratives
 La gestion des transactions des EJBs peut être
couplée avec une implémentation de JTA (Java
Transaction API)
 Spring n’est pas obligatoirement couplé à JTA
diapo 43
Déclarative vs Programmatique
 La gestion programmatique des transactions apporte
un meilleur contrôle et une granularité plus fine et
plus proche du code
 La gestion déclarative des transactions permet de
garder la logique transactionnelle en dehors de la
logique métier
diapo 44
Transactions programmatiques
 Correspond à la gestion des transactions de manière explicite
par des instructions spécifiques dans le code métier traitant de
la persistance
 Les transactions sont gérées explicitement par le développeur
 Exemple :
EntityManagerFactory emf = Persistence.createEntityManagerFactory("tp");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(newInstance);
em.getTransaction().commit();
em.close();
emf.close();
diapo 45
Transactions déclaratives
 Spring comme JAVA EE permet d’utiliser la fonctionnalité des transactions
déclaratives sur les POJOs
 Les transactions déclaratives :
 Réalisées grâce à une approche AOP
 Une transaction peut être vue comme un aspect qui intercepte une méthode (Around
Advice)
 Le développeur spécifie par métadonnées (hier xml, aujourd’hui annotations) les
caractéristiques du contexte transactionnel nécessaire à chaque méthode
 Exemple :
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public void processCode(final String pCode) {
// instructions...
}
diapo 46
Les attributs transactionnels
• Les transactions déclaratives sont configurées par des
attributs transactionnels
• Ils définissent la politique et les comportements
transactionnels des méthodes
– sur les propagations des transactions
– sur les niveaux d’isolation
– Et aussi :
• sur les optimisations Read-only
• sur les Timeouts
diapo 47
Propagation des transactions (1/8)
 Sept modes de propagation des transactions sont
disponibles :
 MANDATORY
 NESTED
 NEVER
 NOT_SUPPORTED
 REQUIRED
 REQUIRES_NEW
 SUPPORTS
diapo 48
Propagation des transactions (2/8)
• PROPAGATION_MANDATORY
– Indique que la méthode doit s’exécuter dans une
transaction, une exception est lancée si aucune transaction
n’est définie
Client
Service
sans TX
TX1
X
DAO
Exception
TX1
PROPAGATION_MANDATORY
diapo 49
Propagation des transactions (3/8)
• PROPAGATION_NESTED
– Indique que la méthode doit s’exécuter dans une transaction
imbriquée si une transaction existante est en cours. La transaction
imbriquée peut avoir un Commit ou un RollBack indépendant de la
transaction existante. Si aucune transaction existante, se comporte
comme PROPAGATION_REQUIRED
Client
Service
sans TX
DAO
TX1
TX1
TX2
PROPAGATION_NESTED
diapo 50
Propagation des transactions (4/8)
• PROPAGATION_NEVER
– Indique que la méthode ne doit pas s’exécuter dans un
contexte transactionnel, une exception est lancée si une
transaction est en cours
Client
Service
sans TX
TX1
sans TX
X
Exception
PROPAGATION_NEVER
diapo 51
DAO
Propagation des transactions (5/8)
• PROPAGATION_NOT_SUPPORTED
– Indique que la méthode ne doit pas s’exécuter dans un
contexte transactionnel. Si une transaction est en cours,
celle ci est suspendue pour la durée d’exécution de la
méthode
Client
Service
DAO
sans TX
sans TX
TX1
sans TX
PROPAGATION_NOT_SUPPORTED
diapo 52
Propagation des transactions (6/8)
• PROPAGATION_REQUIRED
– Indique que la méthode doit s’exécuter dans un
contexte transactionnel. Si une transaction est en cours,
celle ci est utilisée, sinon une nouvelle transaction est
initiée.
Client
Service
sans TX
TX1
TX1
TX1
PROPAGATION_REQUIRED
diapo 53
DAO
Propagation des transactions (7/8)
• PROPAGATION_REQUIRES_NEW
– Indique que la méthode doit s’exécuter dans son propre contexte
transactionnel. Si une transaction est en cours, une nouvelle
transaction est initiée et la transaction existante est suspendue
pour la durée d’exécution de la méthode
Client
Service
DAO
sans TX
TX1
TX1
TX2
PROPAGATION_REQUIRES_NEW
diapo 54
Propagation des transactions (8/8)
• PROPAGATION_SUPPORTS
– Indique que la méthode n’exige pas un contexte
transactionnel, mais peut s’exécuter dans une
transaction si elle existe
Client
Service
sans TX
DAO
sans TX
TX1
TX1
PROPAGATION_SUPPORTS
diapo 55
L’isolation des transactions (1/2)
• Dans une application d’entreprise, les transactions s’exécutent
de manière concurrente sur des données communes
• La concurrence des actions peut mener aux problèmes
suivants :
• Dirty read
– Lectures pouvant se produire sur des données non encore "comitées"
par une autre transaction. En cas de Rollback les données obtenues
sont invalides
• Nonrepeatable read
– Se dit d’une transaction qui exécute une même requête plusieurs fois
et récupère des données pouvant être différentes. La différence étant
due à une autre transaction concurrente mettant ces données à jour
diapo 56
L’isolation des transactions (2/2)
• Phantom reads
– Se produit lorsqu’une une transaction lit plusieurs lignes, pendant
qu’une autre transaction concurrente insert des lignes. Sur une
nouvelle requête des nouvelles lignes peuvent apparaitre
• Dans une situation idéale, les transactions concurrentes
sont complètement isolées les une des autres, pour éviter
les problèmes cités précédemment
• Mais l’isolation parfaite affecte les performances
– Lock des lignes et parfois des tables!
– Le lock agressif oblige les transactions à s’attendre entre elles
• Dans certains cas, il peut être intéressant de relâcher les
niveaux d’isolation.
diapo 57
Exemples de niveaux d’isolation
•
•
•
•
•
ISOLATION_DEFAULT
– Utilise le niveau d’isolation par défaut de la base de données.
ISOLATION_READ_UNCOMMITTED
– Permet de lire des données d’autres transactions concurrentes non encore "comitées".
Peut engendrer des dirty reads, phantom reads et nonrepeatable reads.
ISOLATION_ READ_COMMITTED
– Permet de lire des données d’autres transactions concurrentes uniquement "comitées".
Évite les dirty reads mais pas les phantom reads et nonrepeatable reads.
ISOLATION_REPEATABLE_READ
– Les lectures multiples sur un même champ produisent les mêmes résultats. Évite les dirty
reads et les nonrepeatable reads mais pas les phantom reads.
ISOLATION _SERIALIZABLE
– Niveau d’isolation ACID complet, évite les dirty reads, les nonrepeatable reads et les
phantom reads. C’est le moins performant des niveaux d’isolation (mis en œuvre de locks
plus important).
Note : tous ces niveaux d’isolation ne sont pas supportés par toutes les sources
de données.
diapo 58
JAVA EE : JPA
JAVA EE : JPA
– JPA : Java Persistence API
– À l’origine, JPA est une API visant à normaliser la
gestion de la persistance dans une application
JAVA EE face à une base relationnelle.
– JPA évolue pour intégrer les notions de
persistances non-relationnelles (noSQL, etc.) et est
de plus en plus couplé à la problématique de la
validation (« Bean validation », JSR-303)
JAVA EE : JPA
– Historique :
• JPA 1.0 :
– En 2006 via JSR-220
– Périmètre initial
• JPA 2.0 :
– En 2009 via JSR-317
– Améliorations notables : Criteria, Validation, Mapping
extensions, …
• JPA 2.1 :
– En 2013 via JSR-338
– Améliorations notables : Custom converters, entity graphs,
stored procedures, …
JAVA EE : JPA
• JAVA JPA couvre essentiellement trois domaines
– API de persistance :
• dans le package javax.persistence, nous y trouvons notamment
des « entity manager », « transaction manager », etc. Cette API
permet de cadrer le périmètre de gestion des requêtes,
transactions, erreurs courantes, … via des interfaces (contrat).
• Principales notions :
– EntityManagerFactory : usine à EntityManager
– EntityManager : Facade d’accès à une session de persistance
– EntityTransaction : Interface de manipulation des transactions
(commit, rollback, …)
JAVA EE : JPA
• JAVA JPA couvre essentiellement trois domaines
– API de persistance :
• Principales notions :
– Query : Interface de gestion d’une requête donnée
(exécution, mise à jour, etc.)
– Criteria : Interface alternative de gestion d’une requête
donnée
– FlushMode : Mode de réalisation des opérations en base de
données
• La « session de persistance » est une notion
centrale
JAVA EE : JPA
• JAVA JPA couvre essentiellement trois domaines
– JPQL
• Langage de requêtage très proche de SQL : permet de manipuler
directement les éléments objets (classes, attributs) avec les mots
clef SELECT/FROM/WHERE/…
• Issu de HQL (langage spécifique HIBERNATE)
• Fournit des fonctions scalaires indépendantes des moteurs de
base de données
– Métadonnées Objet/Relationnel
• Annotations permettant de « décorer » les entités persistances
• Permet de spécifier le mapping O/R : @Entity, @Table, @Column,
@ManyToOne, @ManyToMany
JAVA EE : JPA
• JAVA EE fournit le cadre (contrats) uniquement
via son JDK. Les implémentations peuvent être
fournies par d’autres éditeurs. Dans le cas de
JPA, ces implémentations sont appelées « JPA
PROVIDER »
• Exemples :
– Hibernate
– TopLink
– OpenJPA
–…
JAVA EE : JPA
• Quel que soit l’implémentation retenue pour un
projet, le JPA PROVIDER manipulera la notion de
« session de persistance »
• Cette notion permet de connaître, à un instant
donné de l’exécution d’un service défini en utilisant
JPA, quels sont les objets qui seront affectés par la
persistance
• Le JPA PROVIDER permet une abstraction de la
source de données. C’est lui qui choisit notamment
quand et comment son modèle mémoire est
synchronisé avec la base de données
Session de persistance (1/3)
Un JPA Provider tel que Hibernate ne manipule pas directement
les POJOs, mais des proxys obtenus par introspection.
Les proxys contiennent les propriétés du POJO,
ainsi que des informations utilisées par le JPA PROVIDER
diapo 67
Session de persistance (2/3)
La session de persistance est un cache au niveau
transactionnel. C'est elle qui contient les proxys.
Son cycle de vie est géré par le container (Server JAVA EE
typiquement), qui peut se charger aussi de créer la
transaction et de la committer ou roll-backer.
Un objet en session est persistant : objet qui a été récupéré
ou sauvé en base.
Un objet qui n'est pas en session est transient.
Avant de créer une relation entre un objet persistant et un
objet transient, il est nécessaire de rendre ce dernier
persistant.
diapo 68
Session de persistance (3/3)
Cycle de vie d’un entity JPA
diapo 69
GMIN30F
Réutilisation / Composants
Intervenant : André Morassut
Téléchargement