Blue Flower

Chercher

I.  Le Framework Spring MVC

1. Présentation

1.1. Généralités

Le framework Spring MVC de Spring a une architecture de type MVC (Model-View-Controller) et ses composants  servent  pour développer des applications Web flexibles et faiblement couplées. Le modèle MVC permet de séparer les différentes  parties d'une application web à savoir la gestion de requêtes d'entrée envoyées par le client, la logique métier et logique UI (affichage résultats en réponses aux requêtes) tout en assurant un couplage moins fort (Lazy) entre les différentes classes de l'application.

  • La partie Modèle encapsule les données de l'application; ces données sont en général définies et traitées par des simples  POJO (simple classe java).
  • La partie Vue est responsable du rendu des données du modèle et, en général, elle génère une sortie HTML que le navigateur du client peut interpréter.
  • La partie Contrôleur est responsable du traitement des demandes des utilisateurs et de la construction d'un modèle de vue approprié pour le rendu du résultat

Dans  Spring-MVC le contenair (conteneur) sert à créer:

  • Le contexte de l’application Web
  • Les objets traitant les requêtes (Controller)
  • Les objets créant les pages HTML (View)
  • Les objets données des formulaires (les requêtes)
  • Les liens avec les couches métiers et BD
  • Le mapping des URL vers les contrôleurs
  • Le mapping des vues, etc.

Le fait que dans Spring on ait un couplage moins fort (couplage lazy) entre les différentes classes est dû au concept de programmation appelé IoC (Inversio of Control); celui-ci offre un  mécanisme qui facilite la mise en place des dépendances entre les classes par l'injection automatique des objets. Sous Spring,les objets traités sont  des beans et l' injection automatique des objets se fait en se servant de fichiers XML, soit par des annotations, soit  par les constructeurs ou les Setters des beans.
L'inversion de contrôle  laisse au conteneur en l'occurrence ici celui de Spring la responsabilité de gérer le cycle de vie des objets. Avec l'IoC on  référence des interfaces ou des classes plus génériques ce qui permet d'avoir un code clair, réutilisable et facile à tester. L’inversion de contrôle permet de changer le comportement de l’application, en modifiant la description xml du conteneur, sans changer les éléments programmés!
Sans IoC  la création d'objets se ferait par l'opérateur  new et cette création d'objets par instanciation  augmente les dépendances (couplage fort) entre classes.

1.2. Le modèle

Dans le contexte de Spring MVC, un modèle représente généralement les données qui seront transmises vers la vue depuis une opération (définie dans un contrôleur Web) . Spring MVC prend en charge diverses options et modèles pour définir les données pouvant être échangées. Une application Spring MVC typique peut utiliser une combinaison de ces options. La flexibilité de Spring MVC permettant d’avoir un contrôle fin pour la définition des modèles est très puissante, mais elle s'accompagne d’une variabilité et d’une complexité considérables dans la mise en oeuvre..

Une méthode d'un contrôleur dans Spring peut prendre en charge ou pas des paramètres d'entrée, et les principaux mécanismes de Spring permettant de spécifier ces paramètres d'entrée sont les annotations @RequestParam et @ModelAttribute. L'annotation @RequestParam est utilisée pour lier des paramètres de requête individuels, tels que des chaînes et des entiers, aux paramètres de méthode du contrôleur. L'annotation @ModelAttribute est utilisée pour lier des objets complexes, tels que des objets de domaine, des objets de transfert de données et / ou des objets de sauvegarde de formulaire, aux paramètres de méthodes d'un contrôleur.

Une méthode d'un contrôleur dans Spring peut également retourner des données issues d'un modèle. Le principal mécanisme utilisé dans Spring pour spécifier les données de modèle de sortie est l'objet ModelAndView. Si la méthode ne renvoie pas des données, la méthode du contrôleur peut simplement renvoyer une chaîne représentant la vue à restituer. Si la méthode du contrôleur renvoie des données, un objet ModalAndView doit être instancié et chaque variable de sortie est ajoutée en tant qu'attribut de modèle à l'objet ModelAndView.

1.3. La vue

Dans  Spring MVC, une vue génère l'interface utilisateur en fonction des données issues du modèle. Il existe diverses technologies basées sur JAVA pour l'implémentation de vues, mais Java ServerPages (JSP) est la technologie prédominante pour la définition de vues. Les JSP sont conçus pour être implémentés de manière optimisée pour les concepteurs Web.

1.4. Le contrôleur

Le Front contrôleur  traite les requêtes provenant de l'extérieur et de ce fait:

  1. Il analyse l'URL de la requête,
  2. Il appelle le contrôleur qui doit traiter la requête; ce dernier renvoie un objet de type Modèle et le nom logique de la page qui sert à construire la page à afficher,
  3. Il appelle la page demandée et celle-ci  construit la réponse
  4. Il renvoie la réponse au client demandeur.

Le contrôleur du framework Spring MVC, la servlet DispatcherServlet gère donc toutes les requêtes et réponses HTTP de toutes les applications développées avec Spring MVC. Le workflow de traitement des requêtes de Spring  MVC  est illustré dans le diagramme présenté à coté. la servlet DispatcherServlet est en faite le tour de contrôle  de Spring MVC, précisément c'est le Contrôleur dans le Design Pattern MVC. Chaque requête Web  traitée par Spring MVC passe par cette servlet DispatcherServlet. C'est une implémentation du Pattern  Front Controller; il fournit un point d’entrée unique dans toute  application Spring MVC. C'est aussi le pont entre Java et Spring. La servlet  DispatcherServlet est, comme tout autre Servlet d'une application web Java EE, déclarée dans le fichier web.xml avec un modèle d’URL, mais la seule particularité est que le modèle d’URL pour la servlet de répartition est suffisant pour mapper chaque requête Web à DispatcherServlert.

En résumé on a la servlet org.springframework.web.servlet.DispatcherServlet qui est le point d’entrée générique qui délègue les requêtes à des Controller
et en principe à un org.springframework.web.servlet.mvc.Controller qui prend en charge une requête,  utilise la couche métier pour répondre en fabriquant  un modèle sous la forme d’une java.util.Map qui contient les éléments de la réponse. C'est le Controller qui choisit une org.springframework.web.servlet.View qui sera
paramétrée par la Map pour donner la page qui sera affichée.

1.4.1. Implémentation du front controller

L'implémentation du front Controller se fait par configuration dans le ficheir web.xml; en voici un exemple :

<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>

</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

On verra plus bas les détails sur un fichier "web.xml"; toutefois il faut retenir que "appServlet" est le nom qu'on donne à une instance de la servlet "DispatcherServlet" tout au long de l'application.

II. La  configuration dans Spring

1. Présentation

1.1.  La configuration par fichier xml

La configuration de Spring se fait soit par programmation  soit  par fichiers XML. Dans la configuration par fichiers XML les classes représentées sont des beans. Si on utilise les annotations, on peut réduire et même éviter certains des  fichiers XML de configuration. Cependant, les fichiers de configuration XML sont très populaires et faciles à utiliser. Un des principaux fichiers de configuration de Spring MVC est  web.xml.

1.1.1. le fichier web.xml

Le fichier de configuration web.xml contient le point d'entrée de l'application à savoir la servlet  DispatcherServlet le contrôleur qui traite les requêtes en entrée. Ce fichier "web.xml" est défini  dans le répertoire "WebContent/WEB-INF" de l'application. Dans son lancement Spring initialise le contrôleur  DispatcherServlet, puis charge le contexte de l’application à partir d'un fichier dont le nom est de la forme  [nom_servlet]-servlet.xml situé lui aussi dans le répertoire "WebContent/WEB-INF". Voir la valeur de la partie  entre-crochet ([nom_servlet]) dans  la balise <param-value> dans le fichier web.xml.

Remarque:
A partir de Spring .3.0 on définit le fichier "[nom_servlet]-servlet.xml" dans le  répertoire  "WebContent/WEB-INF/spring" et le fichier web.xml est devenu optionnel.

Lorsque la servlet DispatcherServlet est initialisée, elle initialise un objet "org.springframework.web.context.WebApplicationContext" (qui dérive de ApplicationContext) dont une des implémentations   donne l'objet "org.springframework.web.context.support.XmlWebApplicationContext". Cet objet XmlWebApplicationContext contient la configuration de tous les beans de l'application qui seront définis  dans le conteneur Spring. Cet objet utilisera le fichier de configuration Spring  [nom-servlet]-servlet.xml.

on peut définir plusieurs Servlets dans "web.xml". Chaque servlet peut être initialisé, mappé à différentes URL;  on aura ainsi plusieurs conteneurs Spring correspondant à chaque servlet.  Dans ce cas, certaines définitions de beans peuvent être répétées dans de nombreux conteneurs Spring; on a créée org.springframework.web.context.ContextLoaderListener pour résoudre ce problème; par conséquent on a la création d'un contexte org.springframework.web.context.WebApplicationContext racine pour toute l'application web; ce contexte racine est partagé par toutes les servlets. ContextLoaderListener utilisera le nom de fichier défini dans la balise <param-value> comme nom du contexte racine de l'application.

Dans le fichier root-context.xml, nous définirons le bean, les propriétés partagées entre les conteneurs Spring, chaque conteneur Spring dans chaque servlet  utilisera le bean, ses propriétés et les attributs définis pour lui-même

1.1.2. Exemple de fichier web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0" > <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/root-context.xml </param-value>
</context-param>  
<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
       <param-name>contextConfigLocation</param-name> getRootConfigClasses()
<param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*</url-pattern>
</servlet-mapping>
.......
</web-app>

1.1.3. Détail du fichier web.xml

  1. Balise "<context-param>"
    L'existence de cette balise au sein de "web.xml" sert à définir le contexte général de l'application i.e "ApplicationContext"; en effet lorsque on aura une application web qui nécessitera plusieurs "[nom_servlet]-servlet.xml"  donc plusieurs servlets, on y déclarera les différents beans qui sont utilisées  dans le fichier de configuration dont le nom est sous la balise <param-value> de la balise  <context-param>.
  2. Balise "<listner>"
    ....
  3. Balise "<listner-class>"
    ....
  4. La balise <servlet>
    Sous la balise "<servlet>" on a déclaré une balise "<servlet-name>" qui définit le nom d'une instance de la servelt DispatcherServlet en l'occurrence ce nom est "dispatcher" ici dans notre exemple; cette instance sera initialisée avec un paramètre nommé "contextConfigLocation" qui contient le chemin d'accès au fichier  de configuration  "dispatcher-servlet.xml".
    On a aussi sous  cette balise "<servlet>" la balise "<load-on-startup>" qui est une valeur  entière qui spécifie l'ordre de chargement si jamais on a dans web.xml déclaré  plusieurs servlets. Ainsi, si vous devez déclarer plusieurs servlets, vous pouvez définir dans quel ordre elles seront initialisées. Les servlets marquées avec des entiers inférieurs sont chargés avant les servlets marquées avec des entiers plus élevés.
  5. Balise  <servlet-class>
    ....
  6. Balise  <servlet-mapping>
    Avec cette balise "<servlet-mapping>", nous le lions la servelt par son nom à un modèle d’URL qui spécifie les requêtes HTTP qu’il traitera.
  7. Balise  <url-pattern>
    ....
  8. Balise  <servlet-name>
    Sous la balise <servlet-name> est défini le nom d'une instance de la servlet DispatcherServlet
  9. Balise <load-on-startup>
    Sous cette balise est définie  une valeur  entière qui spécifie l'ordre de chargement des servlets si jamais on a dans web.xml déclaré  plusieurs servlets

... 

....

1.1.4. WebApplicationContext

Dans toute application Java EE on dispose d'une interface ApplicationContext qui fournit toutes les informations de configuration. Le framework Spring  propose plusieurs classes qui implémentent cette interface qui représente le contexte racine de l'application; tous les différents éléments de configuration de l'application sont définis dans  le fichier de configuration applicationContext.xml qui est chargé par le ContextLoaderListener (voir le fichier web.xml ).

Pour une application web, le contexte est spécifié par l'interface WebApplicationContext qui étend ApplicationContext et qui ajoute une méthode de récupération de l'API Servlet standard ServletContext pour l'application Web. Outre les standardscopes ( portées )  singleton et prototype  des beans Spring, trois scopes supplémentaires sont disponibles dans un contexte d'application Web:

  • request - étend une définition de bean unique au cycle de vie d'une requête HTTP unique; c'est-à-dire que chaque requête HTTP a sa propre instance d'un bean créé à l'arrière d'une définition de bean unique.
  • session - étend une définition de bean unique au cycle de vie d'une session HTTP.
  • application - étend une définition de bean unique au cycle de vie d'un ServletContext.

1.1.5. Le fichier [nom_servlet]-servlet.xml

Nous avons vu plus haut que spring charge springMVC-servlet.xml ([nom du servlet] -servlet.xml) par défaut à partir du répertoire WEB-INF. On peut remplacer ce comportement par défaut en se servant du paramètre contextConfigLocation comme paramètre d'initialisation (voir dans la balise   <init-param>  de web.xml) de DispatcherServlet. Dans ce qui suit, nous pouvons charger dispatcher-servlet.xml au lieu de springMVC-servlet.xml en donnant comme valeur de la balise  <init-param> la valeur "dispatcher".

Exemple de fichier [nom_servlet]-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   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
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">">

   <context:component-scan base-package="com.omara.business" />
 
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp/" />
      <property name="suffix" value=".jsp"/>
   </bean>
 
</beans>

....

1.1.6.Détail du fichier  [nom_servlet]-servlet.xml

le fichier [nom_servlet]-servlet.xml s'appelle fichier de contexte pour l'application. Dans une application on peut avoir plusieurs fichiers de contexte; ce fichier  a pour rôle l'analyse des composants de l'application, des annotations Web Spring (@Controller)  mais aussi il configure  le modèle. Le framework Spring charge le contexte de l'application à partir de ce fichier [nom_servlet]-servlet.xml.

  1. La balise <context: composant-scan  ...>
    permet d'activer l'analyse des annotations Spring MVC,
  2. La balise <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver> est utilisé pour définir les règles permettant de résoudre les noms de vue.
  3. ....
  4. ....

2.1.  La configuration par programmation

Depuis la spécification Servlet 3.0, on peut développer une  application Spring  sans utiliser des fichiers de configuration "xml" . Comme toutes les  servlets, la servlet org.springframework.web.servlet.DispatcherServlet a nécessite une configuration  pour que le conteneur Web puisse l'amorcer et le mapper afin qu'elle puisse traiter les requêtes;  cette  configuration de DispatcherServlet est un processus bidirectionnel. Tout d'abord, on doit préciser  au conteneur de charger la servlet et de la   mapper à un ou plusieurs Urlpatterns. Après l'amorçage, la  servlet utilise le contexte de l'application (org.springframework.web.context.WebApplicationContext ) pour se configurer. Ainsi la servlet va  détecter les composants nécessaires à partir de ce contexte de l'application et si elle ne le trouve pas, elle  utilisera les valeurs  par défaut (dans la plupart des cas). Toute ces différentes étapes vont se faire par programation en commençant par l'amorçage DispatcherServlet.

... 

2.1. Amorcer  DispatcherServlet

 La spécification Servlet 3.0 a introduit plusieurs options pour configurer et enregistrer une servlet:

  1. utilisation d'un fichier web.xml.
  2. utilisation d'un web-fragment.xml.
  3. utilisation de javax.servlet.ServletContainerInitializer.
  4. On peut obtenir une quatrième option en implémentant  l'interface org.springframework.web.WebApplicationInitializer

Ici c'est la troisième option qui nous intéresse i.e l'utilisation de  "javax.servlet.ServletContainerInitializer". La servlet DispatcherServlet a besoin de WebApplicationContext qui doit contenir tous les beans concernées la configuration; toutefois, par défaut, DispatcherServlet crééra un "org.springframework.web.context.support.XmlWebApplicationContext" et de ce faite  Toute application Spring est à même charger la servlet "org.springframework.web.servlet.DispatcherServlet" et le mapper à toutes les requêtes arrivant sur "/ *".

La configuration de servlet par programmation est assurée par l'interface ServletContainerInitializer et Spring l'implémente  via la classe SpringServletContainerInitializer qui gère d'autres interfaces comme WebApplicationInitializer qui  permet la configuration du contexte (ServletContext ) par programmation.
La classe AbstractAnnotationConfigDispatcherServletInitializer implémente WebMvcConfigurer qui, à son tour implémente en interne WebApplicationInitializer, enregistre un ContextLoaderlistener (optionnelle) et un DispatcherServlet ce qui permet d'ajouter facilement des classes de configuration à charger pour les deux classes, d'appliquer des filtres au DispatcherServlet et de fournir le mappage de servlets.

Remarque:
Dans une configuration type, le contexte racine est chargé par ContextLoaderListener et le contexte de servlet par DispatcherServlet.

2.1.1. exemple de configuration par programmation

La classe AppInitializer
Cette classe étend la classe abstraite AbstractAnnotationConfigDispatcherServletInitializer et on a vu que celle-ci gère "WebMvcConfigurer" et "WebApplicationInitializer" donc elle va amorcer DispatcherServlet et permettre de réaliser les différentes configurations attendues.

package com.omara.springdataJPA.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  @Override
  protected Class<?>[] getRootConfigClasses() {	
    return new Class[] {
	PersistenceJPAConfig.class
   };
 }
 @Override
 protected Class<?>[] getServletConfigClasses() {
  // TODO Auto-generated method stub
 return new Class[] {
  WebMvcConfig.class
  };
}
 @Override
 protected String[] getServletMappings() {
  // TODO Auto-generated method stub
  return new String[] {
   "/"		
 };
}

}

2.1.2. Détails

Dans cette classe  on implémente trois méthodes à savoir getRootConfigClasses(), getServletMappings() et getServletConfigClasses():

1. getRootConfigClasses()
Elle retourne "PersistenceJPAConfig.class"; cet objet va permettre de définir et de configurer la base de donnée de l'application (Datasource), de préciser l'implémentation à utiliser pour la specification JPA ( HibernateJpaVendorAdapter ) et les propriétés additionnelles dont on a besoin ( voir objet Properties):
PersistenceJPAConfig.java

package com.omara.springmvc.config;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@PropertySource({
    "classpath:database.properties"
})
@ComponentScan({
    "com.omara.springmvc"
})
@EnableJpaRepositories(basePackages = "com.omara.springmvc.repository")
public class PersistenceJPAConfig {

    @Autowired
    private Environment env;

    public PersistenceJPAConfig() {
        super();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        final LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPackagesToScan(new String[] {
            "com.omara.springmvc.entity"
        });

        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setJpaProperties(additionalProperties());

        return entityManagerFactoryBean;
    }

    final Properties additionalProperties() {
        final Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
        hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
        hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
        // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
        return hibernateProperties;
    }

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.user"));
        dataSource.setPassword(env.getProperty("jdbc.pass"));
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
}

...

Dans une application Spring type, il existe deux objets qui représentent deux instances de contexte pour l'application; l'une est ApplicationContext,  le contexte de la racine de l'application et la seconde  est le contexte de l'application en tant que servlet. Le contexte de la racine de l'application  contient généralement des ressources partagées/générales comme DataSource, des services, des référentiels, etc. Le contexte de l'application en tant que servlet contient des beans spécifiques à ce contexte, généralement des choses comme le résolveur de vues, les mappages de gestionnaires, les contrôleurs, etc. Le contexte de servlet utilise le contexte racine comme un parent et peut ainsi voir les beans définis là-dedans (la racine ne connaît pas les contextes de servlet!).
Ainsi, getRootConfigClasses () configurera ContextLoaderListener -  c' est  facultatif (on peut retourner null ou un tableau vide).

2. GetServletConfigClasses ()
Elle configure le DispatcherServlet (et est requis).
....

3. getServletConfigClasses()
...

...... 

L'interface WebMvcConfigurer

La classe WebMvcConfig ci-dessous implément l'interface WebMvcConfigurer; cette dernière

package com.omara.springmvc.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * @author Aly OMARA
 */

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.omara.springDataJPA"})
public class WebMvcConfig implements WebMvcConfigurer {
   @Bean
   public InternalResourceViewResolver resolver() {
      InternalResourceViewResolver resolver = new InternalResourceViewResolver();
      resolver.setViewClass(JstlView.class);
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".jsp");
      return resolver;
   }
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
  registry
 .addResourceHandler("/resources/**")
 .addResourceLocations("/resources/");
 }
   @Bean
   public MessageSource messageSource() {
      ResourceBundleMessageSource source = new ResourceBundleMessageSource();
      source.setBasename("messages");
      return source;
   }
 
   @Override
   public Validator getValidator() {
      LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
      validator.setValidationMessageSource(messageSource());
      return validator;
   }
}

....

  • WebMvcConfigurer définit des options pour la personnalisation ou l'ajout à la configuration Spring MVC par défaut activée via @EnableWebMvc.    
  •  @EnableWebMvc active la configuration Spring MVC par défaut et enregistre les composants d'infrastructure Spring MVC attendus par DispatcherServlet.     
  • @Configuration indique qu'une classe déclare une ou plusieurs méthodes @Bean et peut être traitée par le conteneur Spring pour générer des définitions de bean et des demandes de service pour ces beans lors de l'exécution.   
  •  L'annotation @ComponentScan est utilisée pour spécifier les packages de base à analyser. Toute classe annotée avec @Component et @Configuration sera analysée.  
  •  InternalResourceViewResolver aide à mapper les noms des vues logiques pour afficher directement les fichiers dans un certain répertoire préconfiguré.     
  • ResourceBundleMessageSource accède aux ensembles de ressources à l'aide de noms de base spécifiés (ici, il s'agit de messages).    
  •  LocalValidatorFactoryBean démarre javax.validation.ValidationFactory et l'expose via l'interface Spring Validator, l'interface JSR-303 Validator et l'interface ValidatorFactory elle-même.  

3. Les interfaces BeanFactory et ApplicationContext
L'interface BeanFactory (le container et l'interface porte le même nom) fournit un mécanisme avancé de configuration des beans managés, utilisant potentiellement n'importe quel type de stockage.
L'interface ApplicationContext (le container et l'interface porte le même nom) est construite au dessus de la classe BeanFactory; il y  ajoute d'autres dispositifs comme l'intégration plus facile avec l'AOP, la manipulation des messages (pour l'internationalisation), la propagation des événements, les mécanismes déclaratifs pour créer l'ApplicationContext et les contextes parents optionnels,  et des contextes spécifiques aux couches des applications comme WebApplicationContext qui dérive de l'interface ApplicationContext et qui est spécifique aux applications Web.

...

(à suivre)...

précédent