SPRING – Injection de Dépendances

Page 1 sur 33Lecteur de document UniversityLib

SPRING – Injection de Dépendances

Programming, Architecture des Systèmes d’Information, JavaEE · course

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

Publicité

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

Publicité

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

Publicité

• 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)

Publicité

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