SPRING – Injection de Dépendances
UP ASI : Bureau E204
(Architectures des Systèmes d’Information)
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
1
Plan du Cours
– Inversion de Contrôle IoC
– Injection de Dépendances ID
– Bean : Configuration, Stéréotypes, Portées
– Configuration de l’ID avec XML + TP1
– Configuration de l’ID avec Java + TP2
– Configuration de l’ID avec les Annotations + TP3
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
2
Dépendance entre objets ?
• Les objets de la classe C1 dépendent des objets de la classe C2 si :
– C1 a un attribut objet de la classe C2
– C1 hérite de la classe C2
– C1 dépend d’un autre objet de type C3 qui dépend d’un objet de type C2
– Une méthode de C1 appelle une méthode de C2
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
3
Dépendance entre objets ?
• En programmation objet classique Le développeur :
– Instancie les objets nécessaires pour le fonctionnement de son application
(avec l’opérateur new)
– Prépare les paramètres nécessaires pour instancier ses objets
– Définit les liens entre les objets
• Avec Spring
– Couplage faible
– Injection de dépendance
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
4
Couplage : rappel
• Le couplage est une métrique indiquant le niveau d’interaction entre deux
ou plusieurs composants logiciels (Class, Module…)
• On parle de couplage fort
si les composants échangent beaucoup d’information.
• On parle de couplage faible
si les composants échangent peu d’informations.
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
5
Couplage fort
• La classe A ne peut fonctionner que à la présence de la classe B !!
• Si une nouvelle version de la classe B (soit B2), est créée, on est obligé de
modifier dans la classe A.
• Modifier une classe implique:
― Il faut disposer du code source.
― Il faut recompiler, déployer et distribuer la nouvelle application aux
clients. Ce qui engendre des problèmes de la maintenance de
l’application
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
6
Couplage fort : exemple
• De ce fait nous avons violé le principe « une application doit être fermée à la
modification et ouverte à l’extension »
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
7
Couplage faible
• Pour Utiliser le couplage faible nous devons utiliser les interfaces…
• Avec le couplage faible, nous pourrons créer des applications fermées à
la modification et ouvertes a l’extension.
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
8
Inversion de Contrôle
• L’IOC (Inversion Of Control) est un Patron de conception
• Permettant de dynamiser la gestion de dépendance entre objets
• Facilitant l’utilisation des composants
• Minimisant l’instanciation statique d’objets (avec l’opérateur new)
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
9
Inversion de Contrôle
• L'exécution de l’application n'est plus sous le contrôle direct de
l'application elle-même mais du Framework sous-jacent.
• Si l'application s'exécute dans un Framework, celui est représenté par un
conteneur à l’exécution :
– celui-ci prend le contrôle du flot d'exécution et gère notamment la résolution
Advertisement
des dépendances
– l'application s'insère dans le cadre qu'il fixe
– Il y a donc inversion de contrôle
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
10
Injection de Dépendances
•
Toute application Java est une composition d'objets qui collaborent pour
rendre le service attendu
– Les objets dépendent les uns des autres
• Dans notre cas, nos applications web seront contrôlées par le Framework
Spring. Comment? :
• L’Injection de Dépendance est la forme principale de l’IoC. Elle
implémente le principe de l’IoC.
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
11
Injection de Dépendances
• L’Injection de Dépendance (ID) est une méthode pour instancier des
objets et créer les dépendances nécessaires entre elles, sans avoir besoin
de coder cela nous même.
• Ceci permet de réduire le code relatif aux dépendances. Ce qui permet
une lisibilité du code, et permet de gagner en temps de développement.
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
12
Bean – Définition et Portée
• C’est un composant Java spécifique avec un identifiant unique.
• Plusieurs types de Bean (scope):
– singleton : Une seule instance du Bean crée pour chaque Conteneur
IoC Spring, et référencée à chaque invocation), scope par défaut.
– prototype : Nouvelle instance créée à chaque appel du Bean
– request : (Contexte Web uniquement) Nouvelle instance créée pour
chaque requête HTTP.
– session : une instance du bean par session HTTP.
– global-session : une instance du bean par session globale (valable pour
les portlets : ensemble d’applications déployées sur un même
conteneur web).
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
13
Bean – Déclaration et Attributs
• On définit un Bean dans un fichier XML, avec une configuration Java ou par
annotation, pour que Spring puisse le gérer :
•
Les attributs :
– class : fully qualified java class name
– id : the unique identifier for this bean
– configuration : (scope, init-method, etc.)
– property : arguments to pass to the bean setters at creation time
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
14
Configuration Spring : XML, Java, Annotation
• Spring peut se baser sur trois façons différentes pour configurer l’injection de
dépendances et la création des beans (instances) :
• XML (obsolète)
• Java (obsolète)
• Annotations (le plus utilisé)
• Les méta-données permettent à Spring
– d’instancier les beans
– de les configurer
– de les assembler
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
15
Bean – Exemple 1 – XML
• Dans un fichier XML de configuration des beans :
•
Et dans le code java :
public class DependencyController {
IDependencyService myService;
public IDependencyService getMyService() {
return myService;
}
public void setMyService(IDependencyService myService) {
this.myService = myService;
}
}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
16
Bean – Exemple 2 – Java
Advertisement
•
Tout est centralisé dans une seule classe Java (classe de configuration des beans) :
@Configuration
public class BeansConfiguration {
@Bean(name = "dependencyController")
public DependencyController createDependencyControl() {
DependencyController depController = new DependencyController();
depController.setMyService(createDependencyService());
return depController;
}
@Bean(name = "dependencyService")
public DependencyService createDependencyService() {
DependencyService depService = new DependencyService();
depService.setMyRepository(createDependencyRepository());
return depService;
}
…………………
}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
17
Bean – Exemple 3 – Annotations
• Dans la classe Java de configuration des beans. Chaque bean est annoté (Annotation
décentralisée)
@Component
public class DependencyController {
@Autowired
private IDependencyService myService;
…
@Component
public class DependencyService implements IDependencyService {
@Autowired
private IDependencyRepository myRepository;
…
@Configuration // Cherche les beans Spring dans le package : tn.esprit.esponline
@ComponentScan("tn.esprit.esponline")
public class Main {}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
18
Les Stéréotypes des Beans
• Un classe annotée @Component est un bean Spring. C’est une annotation
générique.
•
Il existe plusieurs autres variations de @Component qui s’utilise pour une
sémantique particulière comme :
– @Controller : pour designer le contrôleur du modèle MVC (couche
présentation)
– @Service : pour designer un élément de la couche métier
– @Repository : pour designer un élément DAO (couche persistance de
données)
– ...
• @Service, @Controller, @Repository = { @Component + quelques
autres fonctionnalités }
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
19
TP1 Configuration Spring se basant sur du XML
Nous allons coder ce TP
en pas à pas ensemble :
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
20
TP1 Configuration Spring se basant sur du XML
• Créer un projet Maven Simple de type Jar (tp1-spring-injection-xml)
• Mettre à jour le pom.xml :
– <version>1.0</version>
– Java 1.8
– Dépendance spring-context :
• groupId : org.springframework
• artefactId : spring-context
• version : 5.0.2.RELEASE
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
21
TP1 Configuration Spring se basant sur du XML
• Créer les packages tn.esprit.esponline.controller / tn.esprit.esponline.service /
tn.esprit.esponline.repository
• Créer les beans :
– DependencyController (pas besoin d’interface ici)
– DependencyService et son interface IDependencyService
– DependencyRepository et son interface IDendencyRepository
Advertisement
• Créer la classe Main qui joue le rôle du conteneur IOC Spring
• Voir des Indications dans les pages suivantes :
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
22
TP1 Configuration Spring se basant sur du XML
• Créer le bean RepositoryService (créer de même les beans DependencyControlIer et
DependencyRepository) :
package tn.esprit.espoline.controller;
import tn.esprit.espoline.service.IDependencyService;
public class DependencyController {
IDependencyService myService;
public IDependencyService getMyService() {
return myService;
}
public void setMyService(IDependencyService myService) {
this.myService = myService;
}
}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
23
TP1 Configuration Spring se basant sur du XML
• Fichier de configuration XML tp1-beans.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dependencyController"
class="tn.esprit.espoline.controller.DependencyController">
<property name="myService" ref="dependencyService" />
</bean>
<bean id="dependencyService" class="tn.esprit.espoline.service.DependencyService">
<property name="myRepository" ref="dependencyRepository" />
</bean>
<bean id="dependencyRepository"
class="tn.esprit.espoline.repository.DependencyRepository" />
</beans>
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
24
TP1 Configuration Spring se basant sur du XML
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import tn.esprit.espoline.controller.DependencyController;
public class Main {
public static void main(String[] args) {
// Chargement du Conteneur Spring IoC :
ApplicationContext context = new ClassPathXmlApplicationContext("tp1-beans.xml");
System.out.println("Contains dependencyController " +
context.containsBeanDefinition("dependencyController"));
System.out.println("Contains dependencyService " +
context.containsBeanDefinition("dependencyService"));
System.out.println("Contains dependencyRepository " +
context.containsBeanDefinition("dependencyRepository"));
System.out.println((context.getBean(DependencyController.class)).coursesList());
}
}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
25
TP2 Configuration Spring se basant sur Java
• Ce TP2 (tp2-spring-injection-java) est presque le même que le TP1
(tp1-spring-injection-xml).
• A la place d fichier XML, nous allons coder une classe Java de
configuration qui indiquera à Spring quels beans il doit créé dans le
conteneur IoC.
• Dans la classe Demo.java :
// Chargement du Conteneur Spring IoC :
context = new AnnotationConfigApplicationContext(BeansConfiguration.class);
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
26
TP2 Configuration Spring se basant sur Java
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
27
TP3 Configuration Spring avec les Annotations
• Ce TP3 (tp3-spring-injection-annotations) est presque le même que le TP2 (tp2-
spring-injection-java).
• Nous allons utiliser les annotations (@Controller, @Service, @Repository)
•
Advertisement
•
Injecter l’interface Service dans le Controller (@Autowired)
Injecter l’interface Repository dans le Service (@Autowired)
• Ajouter les annotations suivantes dans la classe Main :
@Configuration
@ComponentScan("tn.esprit.espoline")
public class Main {}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
28
TP3 Configuration Spring avec les Annotations
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
29
TP3 Révision Configuration avec les Annotations
package tn.esprit.espoline.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tn.esprit.espoline.repository.IDependencyRepository;
@Service
public class DependencyService implements IDependencyService {
@Autowired
private IDependencyRepository myRepository;
public IDependencyRepository getMyRepository() {
return myRepository;
}
public void setMyRepository(IDependencyRepository myRepository) {
this.myRepository = myRepository;
}
public List<String> getCoursesList() {
return myRepository.getCoursesList();
}
}
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
30
Les Trois Configurations
Java
Annotation
XML
-
-
-
Avantages
Inconvéniants
Conf centralisée dans un seul
endroit.
Typage fort.
Par rapport au annotation, un
code de configuration
supplémentaire à écrire.
-
-
-
-
Bien pour un développement
rapide.
La classe contient déjà sa
configuration
Configuration éparpillée.
Conf et code dans un même
endroit.
Obsolète
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
31
SPRING – Injection de Dépendances
Si vous avez des questions, n’hésitez pas à nous
contacter :
Département Informatique
UP ASI
(Architectures des Systèmes d’Information)
Bureau E204
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
32
SPRING – Injection de Dépendances
© 2020-2021 – ESPRIT – Module Architecture des SI II (Spring + JavaEE) – Injection de Dépendances
33