Vous êtes sur la page 1sur 41

Chapitre 5

Spring Framework
Introduction

• Spring est un framework léger. Il peut être considéré comme un framework de


frameworks car il fournit un support à divers frameworks tels que Struts, Hibernate,
Tapestry, EJB, JSF, etc.

• Au sens large, Spring peut être défini comme une structure où l'on trouve la solution des
divers problèmes techniques.

• Le framework Spring comprend plusieurs modules tels que IOC (Inversion Of Control),
AOP (Aspect Oriented Programming), DAO (Data Access Object), Context, ORM (object-
Relational Mapping), WEB MVC etc.

• Spring est le framework de développement d'applications le plus populaire pour Java EE.
Des millions de développeurs dans le monde utilisent Spring Framework pour créer du code
hautement performant, facilement testable et réutilisable.

22.06.2021
Introduction
• Avantages :

• POJO Based : Il permet de développer à l'aide de POJO. L'avantage est que vous n'avez
pas besoin d'un produit de conteneur EJB tel qu'un serveur d'applications, mais vous avez
la possibilité d'utiliser uniquement un conteneur de servlet robuste.

• Modulaire : Spring est organisé de manière modulaire.

• Intégration avec les frameworks existants : Il ne réinvente pas la roue, mais utilise
réellement certaines des technologies existantes.

• Le framework Web de Spring est un framework Web MVC.

• Gestion centrale des exceptions - Spring fournit une API pratique pour traduire les
exceptions spécifiques à la technologie en exceptions cohérentes et non contrôlées.

22.06.2021
Introduction
• Avantages :

• Léger : Les conteneurs IoC sont légers en particulier par rapport aux conteneurs EJB.
Cela est utile pour développer et déployer des applications sur des ordinateurs avec une
mémoire et des ressources CPU limitées.

• Gestion des transactions : Spring fournit une interface de gestion des transactions
cohérente qui peut passer à une transaction locale (à l'aide d'une seule base de données,
par exemple) et passer à des transactions globales (à l'aide de JTA, par exemple).

• Testabilité : Le test d'une application écrite avec Spring est simple car le code dépendant
de l'environnement est déplacé dans ce framework. De plus, en utilisant les POJO
JavaBeanstyle, il devient plus facile d'utiliser l'injection de dépendances pour injecter des
données de test.

22.06.2021
Architecture

Spring vous permettant de choisir les modules qui vous sont utiles, sans avoir à apporter le
reste. Ainsi, Spring Framework fournit environ 20 modules qui peuvent être utilisés en
fonction des besoins d'une application.

22.06.2021
Architecture

Il se compose des modules Core, Beans, Context et


Expression Language (EL) dont les détails sont les
suivants:

• Le module Core fournit les parties fondamentales


du framework, y compris les fonctionnalités IoC et
Dependency Injection.

• Le module Bean fournit BeanFactory, qui est une


implémentation sophistiquée du Factory Pattern.

• Le module Contexte s'appuie sur Core et Beans et


c'est un moyen d'accéder à tous les objets définis
et configurés. L'interface ApplicationContext est
le point central du module Contexte.

• Le module SpEL fournit un langage d'expression


puissant pour interroger et manipuler un graphe
d'objets au moment de l'exécution.
22.06.2021
Architecture

La couche Accès / Intégration aux données se


compose des modules suivants:
• Le module JDBC fournit une couche d'abstraction
JDBC qui supprime le besoin de codage JDBC
fastidieux.
• Le module ORM fournit des couches d'intégration
pour les API de mappage relationnel objet les plus
courantes.
• Le module OXM fournit une couche d'abstraction
qui prend en charge les implémentations de
mappage objet/XML pour JAXB, Castor …
• Le module JMS du service de messagerie Java
contient des fonctionnalités de production et de
consommation de messages.
• Le module Transaction prend en charge la gestion
des transactions par programmation et déclarative
pour les classes qui implémentent des interfaces
22.06.2021
spéciales et pour tous vos POJO.
Architecture
La couche Web se compose des modules suivants:

• Le module Web fournit des fonctionnalités


d'intégration orientées Web de base telles que la
fonctionnalité de téléchargement de fichiers et
l'initialisation du conteneur IoC à l'aide des
listeners de servlet et d'un contexte d'application
orienté Web.

• Le module Web-MVC contient l'implémentation


MVC de Spring pour les applications Web.

• Le module Web-Socket prend en charge la


communication bidirectionnelle basée sur
WebSocket entre le client et le serveur.

• Le module Web-Portlet fournit l'implémentation


MVC à utiliser dans un environnement de portlet et
22.06.2021
reflète la fonctionnalité du module Web-Servlet.
Application Java avec Spring
1. Créer un projet Maven 3. Créer la classe contenant la méthode « main »
public class App {
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld)
context.getBean("helloWorld");
obj.getMessage();
}
}

4. Créer le bean HelloWorld


2. Ajouter les dépendances au
public class HelloWorld {
fichier « pom.xml » private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("m :"+message);
}
22.06.2021 }
Application Java avec Spring
5. Créer le fichier Beans.xml dans le dossier « src »
<?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-3.0.xsd">

<bean id = "helloWorld" class ="ensa.javaapp.JavaApp.HelloWorld">


<property name = "message" value = "Hello World!"/>
</bean>
</beans>

Par convention, les développeurs nomment ce fichier « Beans.xml », mais vous êtes indépendant pour choisir le nom de
votre choix. Vous devez vous assurer que ce fichier est disponible dans CLASSPATH et utiliser le même nom dans
l'application principale tout en créant un contexte d'application comme indiqué dans le fichier MainApp.java.

Le fichier Beans.xml est utilisé pour attribuer des identifiants uniques à différents beans et pour contrôler la
création d'objets avec des valeurs différentes sans affecter aucun des fichiers source Spring. Par exemple, en
utilisant le fichier suivant, vous pouvez transmettre n'importe quelle valeur pour la variable "message" et vous pouvez
imprimer différentes valeurs de message sans affecter les fichiers HelloWorld.java et MainApp.java.
22.06.2021
Application Java avec Spring
6. Exécuter l’application

• La première étape consiste à créer un contexte d'application dans lequel nous avons utilisé le framework API
« ClassPathXmlApplicationContext() ». Cette API charge le fichier de configuration des beans et éventuellement
basée sur l'API fournie, elle s'occupe de créer et d'initialiser tous les objets, c'est-à-dire les beans mentionnés
dans le fichier de configuration.

• La deuxième étape est utilisée pour obtenir le bean requis en utilisant la méthode getBean() du contexte créé.
Cette méthode utilise l'ID du bean pour renvoyer un objet générique, qui peut finalement être converti en l'objet
réel. Une fois que vous avez un objet, vous pouvez utiliser cet objet pour appeler n'importe quelle méthode de
classe.

22.06.2021
IoC (Inversion of Control) et Spring

• Le conteneur Spring est au cœur du framework Spring. Le conteneur permet de créer les objets, les
lier ensemble, les configure et gérer leur cycle de vie. Le conteneur Spring utilise DI (Dependency
Injection) pour gérer les composants qui composent une application. Ces objets sont appelés Spring
Beans.

• Le conteneur obtient ses instructions sur les objets à instancier,


configurer et assembler en lisant les métadonnées de
configuration fournies. Les métadonnées de configuration
peuvent être représentées par XML, des annotations Java ou du
code Java. Le diagramme suivant représente une vue de haut
niveau du fonctionnement de Spring. Le conteneur Spring IoC
utilise les classes Java POJO et les métadonnées de
configuration pour produire un système ou une application
entièrement configuré et exécutable.

22.06.2021
Bean
<?xml version = "1.0" encoding = "UTF-8"?>
Le conteneur Spring IoC est <beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
totalement découplé du format
xsi:schemaLocation = "http://www.springframework.org/schema/beans
dans lequel ces métadonnées de http://www.springframework.org/schema/beans/spring-beans-
configuration sont réellement 3.0.xsd">
écrites. Voici les trois méthodes
<!– Bean Simple -->
importantes pour fournir des <bean id = "..." class = "...">
métadonnées de configuration au </bean>
conteneur Spring :
<!– Bean avec une initialization lazy -->
<bean id = "..." class = "..." lazy-init = "true">
 Fichier de configuration basé
</bean>
sur XML.
<!– Bean avec une méthode d’initialization -->
 Configuration basée sur les <bean id = "..." class = "..." init-method = "...">
annotations </bean>

 Configuration basée sur Java <!– Bean avec une méthode de destruction -->
<bean id = "..." class = "..." destroy-method = "...">
</bean>
22.06.2021 </beans>
Bean

Pour déterminer la porté d’un Bean (Scope) on utilise l’attribut « scope » de la balise <bean>. Les
valeurs de cet attributs sont:

• Singleton : C’est la valeur par défaut. Une instance par IoC Conterner.

• Prototype :le conteneur Spring IoC crée une nouvelle instance de bean de l'objet chaque fois
qu'une demande pour ce bean spécifique est faite.

• Request : Cela étend une définition de bean à une requête HTTP. Uniquement valable dans le
contexte d'un Spring ApplicationContext sensible au Web.

• Session : Cela étend une définition de bean à une session HTTP. Uniquement valable dans le
contexte d'un Spring ApplicationContext sensible au Web.

• Global-session : Cela étend une définition de bean à une session HTTP globale. Uniquement
valable dans le contexte d'un Spring ApplicationContext sensible au Web.

22.06.2021
Bean Post Processors

L'interface BeanPostProcessor définit des méthodes de callback que vous pouvez implémenter pour
fournir votre propre logique d'instanciation, logique de résolution de dépendance, etc. On peut
également implémenter une logique personnalisée une fois que le conteneur Spring a fini
d'instancier, de configurer et d'initialiser un bean en branchant un ou plusieurs implémentations de
BeanPostProcessor.

Les BeanPostProcessor fonctionnent sur des instances de bean (ou d'objet), ce qui signifie que le
conteneur Spring IoC instancie une instance de bean, et ainsi les interfaces du BeanPostProcessor
peuvent commencer leur travail.

L’ApplicationContext détecte automatiquement tous les beans définis avec l'implémentation de


l'interface BeanPostProcessor et enregistre ces beans en tant que postprocesseurs, pour être
ensuite appelés de manière appropriée par le conteneur lors de la création du bean.

22.06.2021
Bean Post Processors - Exemple

• HelloModel.java
public class HelloModel {
private String message;
public void setMessage(String message) {
this.message = message;
}
public void getMessage() {
System.out.println("Message = "+message);
}
public void init() {
System.out.println(“Call of Init Function");
}
public void destroy() {
System.out.println(“Call of Destroy Function");
}
}

22.06.2021
Bean Post Processors - Exemple

• PostProcessorHelloModel.java

public class PostProcessorHelloModel implements BeanPostProcessor {

public Object postProcessBeforeInitialization(Object bean, String


beanName) throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean;
}

public Object postProcessAfterInitialization(Object bean, String


beanName) throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean;
}
}

22.06.2021
Bean Post Processors - Exemple

• MainApp.java

public class MainApp {


public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

HelloModel obj = (HelloModel) context.getBean("helloBean");


obj.getMessage();
context.registerShutdownHook();
}
}

L’appel de la méthode « registerShutdownHook() » garantira un arrêt en douceur et appellera


les méthodes de destruction appropriées.

22.06.2021
Bean Post Processors - Exemple
• 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-3.0.xsd">

<bean id = "helloModel" class = "ensa.javaapp.JavaApp.HelloModel" init-method = "init"


destroy-method = "destroy">
<property name = "message" value = "Hello World!"/>
</bean>

<bean class = "ensa.javaapp.JavaApp.PostProcessorHelloModel" />

</beans>

22.06.2021
Bean Post Processors - Exemple
• Résultat

BeforeInitialization : helloBean
Call of Init Function
AfterInitialization : helloBean
Message = Hello World!
Call of Destroy Function

22.06.2021
Héritage des Beans

<bean id="hello2" class="ensa.javaapp.JavaApp.Hello2" parent="helloBean">


<property name = "message1" value = "Hello India!"/>
</bean>

Une définition de bean enfant hérite des données de configuration d'une définition
parent. La définition enfant peut remplacer certaines valeurs ou en ajouter d'autres,
si nécessaire.
Lorsque vous utilisez des métadonnées de configuration XML, vous indiquez une
définition de bean enfant à l'aide de l'attribut parent, en spécifiant le bean parent
comme valeur de cet attribut.

22.06.2021
Dependency injection

• Il existe deux critères de qualité d’une conception:

 Cohésion : Mesure l'étendue de la responsabilité d'un module (Classe, Méthode, …).

 Il faut maximiser le degré de cohésion dans une conception.

 Couplage : Le degré de dépendance de chaque module aux autres modules.

 Il faut minimiser le couplage dans une conception.

• Chaque application basée sur Java possède des objets qui fonctionnent ensemble. Lors de l'écriture
d'une application Java complexe, les classes d'application doivent être aussi indépendantes que
possible des autres classes Java pour augmenter la possibilité de réutiliser ces classes et de les
tester indépendamment des autres classes lors des tests unitaires (Couplage). L'injection de
dépendance (Dependency Injection) aide à lier ces classes ensemble tout en les gardant
indépendantes.

22.06.2021
Dependency injection

• Code standard :
public class A { • Un objet de type « A » ne devrait pas s'inquiéter de
private B b;
l'implémentation de l’objet de type « B ». Ainsi « b » va
public A() { être créer indépendamment et sera fourni à « A » au
b = new B(); moment de l'instanciation de « A ». Toute cette
}
} procédure est contrôlée par Spring Framework.

• Code avec inversion de


dépendance : • La deuxième méthode d'injection de dépendance
consiste à utiliser les méthodes Setter de la classe
public class A{
private B b; « A » où nous allons créer une instance de « B ». Cette
instance sera utilisée pour appeler des méthodes setter
public A(B b) {
pour initialiser les propriétés de « A ».
b = b;
}
}
22.06.2021
Injecting Inner Beans

<?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-3.0.xsd">

<bean id = "bean" class = "..." >


<property name = "target">
<bean id = "bean2" class = "..." />
</property>
</bean>

</beans>

22.06.2021
Injecting Collection

<bean id = "javaCollection" class = "..."> <bean id = "javaCollection" class = "...">

<!-- java.util.List --> <!-- java.util.Map -->


<property name = "addressList"> <property name = "addressMap">
<list> <map>
<value>INDIA</value> <entry key = "1" value = "INDIA"/>
<value>USA</value> <entry key = "2" value = "Pakistan"/>
</list> </map>
</property> </property>

<!-- java.util.Set --> <!-- java.util.Properties -->


<property name = "addressSet"> <property name = "addressProp">
<set> <props>
<value>INDIA</value> <prop key = "one">INDIA</prop>
<value>USA</value> <prop key = "two">Pakistan</prop>
</set> <prop key = "three">USA</prop>
</property> </props>
</bean> </property>
</bean>

22.06.2021
Configuration basée sur les Annotations

Le DI basé sur les annotations n'est pas activé par défaut dans le conteneur Spring. Ainsi, avant
de l’utiliser, nous devrons l'activer dans le fichier de configuration Spring (Beans.xml) à l’interieur de
la balise « Beans ».

<context:annotation-config/>

Voici un exemple des annotations qu’on peut utiliser dans nos classes:
 @PostConstruct et @PreDestroy
 @Required
 @Autowired (pour DI)
 @Qualifier

22.06.2021
Configuration basée sur Java Beans

La configuration basée sur les Java Beans permet d'écrire la plupart de votre configuration Spring
sans utiliser le fichier XML (Beans.xml) mais plutôt avec l'aide de quelques annotations :

 @Configuration : indique que la classe peut être utilisée par le conteneur IoC de Spring comme
une source de définition de Bean.
 @Bean : remplace l’id du Bean

@Configuration
ApplicationContext ctx = new
public class HelloWorldConfig {
AnnotationConfigApplicationContext(HelloWorldConfig.class);
@Bean
public HelloWorld helloWorld(){
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
return new HelloWorld();
helloWorld.setMessage("Hello World!");
}
helloWorld.getMessage();
}

22.06.2021
Configuration basée sur Java Beans

La configuration basée sur les Java Beans permet d'écrire la plupart de votre configuration Spring
sans utiliser le fichier XML (Beans.xml) mais plutôt avec l'aide de quelques annotations :

 Injection de dépendances : Dans l’exemple ci-dessous le bean « foo » reçoit une référence à
« bar » via l'injection du constructeur.

@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}

22.06.2021
Configuration basée sur Java Beans

La configuration basée sur les Java Beans permet d'écrire la plupart de votre configuration Spring
sans utiliser le fichier XML (Beans.xml) mais plutôt avec l'aide de quelques annotations :

 @Import(A.class) : permet de charger les définitions des beans (@Bean) depuis une autre
class de configuration.
@Configuration
@Configuration
@Import(AppConfig1.class)
public class AppConfig1 {
public class AppConfig2 {
@Bean
@Bean
public Foo foo() {
public Bar bar() {
return new Foo();
return new Bar();
}
}
}
}

 @Bean(initMethod="…", destroyMethod="…") : permet de définir les méthodes d’initialisation


et de destruction d’un objet.
 @Scope("…") : permet de définir la porté d’un bean.

22.06.2021
Spring MVC

• Le framework Spring Web MVC fournit une architecture Model-View-Controller (MVC) et des
composants prêts qui peuvent être utilisés pour développer des applications Web flexibles et
faiblement couplées.

• Le framework Spring Web model-view-controller (MVC) est conçu autour d'un DispatcherServlet
qui gère toutes les requêtes et réponses HTTP.

22.06.2021
Première application

22.06.2021
Première application

22.06.2021
Première application

22.06.2021
Première application

22.06.2021
Première application

Package dédié à
la configuration
de l’application

MVC

N.B: C’est à nous de créer les packeges « controller »


22.06.2021 et « model » ainsi que le dossier views
Package « ensa.config »
• FrontController.java • AppConfig.java
public class FrontController extends @Configuration
AbstractAnnotationConfigDispatcherServletInitializer{ @EnableWebMvc
@ComponentScan(basePackages = {"ensa"})
@Override public class AppConfig {
protected Class<?>[] getRootConfigClasses() {
return null; @Bean
} public InternalResourceViewResolver resolver() {
@Override InternalResourceViewResolver resolver = new
protected Class<?>[] getServletConfigClasses() { InternalResourceViewResolver();
return new Class<?>[] {AppConfig.class}; resolver.setViewClass(JstlView.class);
} resolver.setPrefix("/WEB-INF/views/");
@Override resolver.setSuffix(".jsp");
protected String[] getServletMappings() { return resolver;
return new String[] {"/"}; }
}
} }

N.B: C’est à nous de définir les noms de ces deux classes. Ils ne sont pas des noms prédéfinit
ou qui doivent être forcément utilisés.
Package « ensa.model » et « views »
public class HelloModel {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message; Hello.jsp
}
} <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>

HelloModel.java
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<%@ page isELIgnored="false" %>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h2>${hello.message}</h2>
</body>
</html>
Package « ensa.controller »

FirstController.java

@Controller
public class FirstController {

@RequestMapping(value="/hello", method=RequestMethod.GET)
public String handler(Model model) {
HelloModel hello = new HelloModel();
hello.setMessage("Test");
model.addAttribute("hello", hello);
return "helloview";
}

• L'attribut « value » indique l'URL vers laquelle la méthode du gestionnaire est mappée.
• L'attribut « method » définit la méthode de service pour gérer la requête HTTP
GET/POST.
Spring Data

• La mission de Spring Data est de fournir un modèle de programmation familier et cohérent


basé sur Spring pour l'accès aux données tout en conservant les caractéristiques spéciales du
magasin de données sous-jacent.

• Il facilite l'utilisation des technologies d'accès aux données, des bases de données
relationnelles et non relationnelles, des frameworks map-reduce et des services de données
basées sur le cloud.

• Il contient de nombreux sous-projets spécifiques à une base de données donnée. Les projets
sont développés en collaboration avec de nombreuses entreprises et développeurs qui sont à
l'origine de ces technologies passionnantes.

• Parmi ces principaux modules:


 Spring Data JDBC
 Spring Data MongoDB
 Spring Data REST
 Spring Data JPA
…
Spring Security

• Spring Security est un framework d'authentification et de contrôle d'accès puissant et


hautement personnalisable. Il est utilisé pour sécuriser les applications basées sur Spring.

• Spring Security est un framework qui se concentre sur la fourniture à la fois


d'authentification et d'autorisation aux applications Java. Comme tous les projets Spring, la
véritable puissance de Spring Security réside dans la facilité avec laquelle elle peut être
étendue pour répondre aux exigences personnalisées.

• Caractéristiques

 Prise en charge complète et extensible de l'authentification et de l'autorisation

 Protection contre les attaques telles que la fixation de session, le détournement de clic,
la contrefaçon de requêtes intersites, etc.

 Intégration de l'API de servlet

 Intégration facultative avec Spring Web MVC


22.06.2021

Vous aimerez peut-être aussi