I. Le Framework Spring MVC
1. Présentation
1.1. Généralités
Spring MVC est un module du framework Spring; son architecture obéit au pattern MVC (Model-View-Controller) et il permet de développer en java des applications Web flexibles et faiblement couplées. Avec le modèle MVC on sépare les 3 parties d'une application web en java à savoir le traitement des requêtes d'entrée envoyées par le client, la logique métier et la logique UI (affichage des résultats en réponses aux requêtes) .
- 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; 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 container (conteneur) gère :
- 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 la Base de Données,
- Le mapping des URL vers les contrôleurs,
- Le mapping des vues, etc.
Le fait que dans Spring MVC 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 soit 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 des annotations comme @RequestParam et @ModelAttribute.
L'annotation @RequestParam est utilisée pour lier des paramètres de requêtes individuels, tels que des chaînes et des entiers, aux paramètres d'une méthode du contrôleur concerné. 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 des vues, mais Java ServerPages (JSP) est la technologie prédominante pour la définition des 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 :
- Il analyse l'URL de la requête,
- 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,
- Il appelle la page demandée et celle-ci construit la réponse
- 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.
On doit mapper les requêtes que le DispatcherServlet gère, en précisant chaque URL dans le fichier WEB-INF/web.xml. Ci-dessous on a un fichier web.xml au sein duquel on montre la déclaration de DispatcherServlet ainsi que le mappage ; dans notre exemple dispatcher est le nom d'une instance de DispatcherServlet dans notre application.
Dans Servlet 2.4 (novembre 2003), un conteneur de servlet (tel que Tomcat et Jetty) démarrait simplement l'application Web en recherchant le fichier WEB-INF/web.xml (le descripteur de déploiement). Le fichier WEB-INF/web.xml contient des références aux servlets, filtres (filters) et listner, avec leurs modèles et paramètres d'URL associés. En utilisant web.xml, le conteneur de servlet sait exactement où trouver tout et comment les configurer.
Depuis Servlet 3.0 (décembre 2009), le fichier WEB-INF/web.xml est facultatif et on peut également utiliser des annotations ou une configuration par programmation à la place.
II. La configuration dans Spring
1. Présentation
1.1. La configuration par fichiers 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. Les principaux fichiers de configuration de Spring MVC son précisés dans web.xml le descripteur de déploiement ( chaque application java web en possède un ) .
1.1.1. le fichier web.xml
Le fichier descripteur de dépoiement "WEB-INF/web.xml", défini dans le répertoire ".../WEB-INF, contient le point d'entrée de l'application à savoir la servlet DispatcherServlet le contrôleur qui traite les requêtes en entrée. Au lancement, Spring initialise le contrôleur DispatcherServlet, puis charge le contexte de l’application à partir du fichier [nom_servlet]-servlet.xml situé lui aussi dans le répertoire ".../WEB-INF" (Voir la valeur de la partie entre-crochet ([nom_servlet]) dans la balise <param-value> sous la la balise <init-param> dans web.xml).
La servlet DispatcherServlet initialise donc 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ée, mappée à différentes URL; certaines définitions de beans peuvent être répétées dans de nombreux conteneurs Spring; org.springframework.web.context.ContextLoaderListener est créée pour traiter ce problème; l'objet org.springframework.web.context.WebApplicationContext définit le contexte racine de toute l'application web; ce contexte racine est partagé par toutes les servlets de l'application . ContextLoaderListener utilisera le nom du fichier défini dans la balise <param-value> à l'intérieur de de la balise <context-param> 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 ce bean, ses propriétés et les attributs définis pour lui-même;
Remarque:
A partir de Spring .3.0 on définit le fichier "[nom_servlet]-servlet.xml" dans le répertoire ".../WEB-INF/spring" et le fichier web.xml est devenu optionnel.
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>
<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
- Balise "<context-param>"
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>. - Balise "<listener>"
Un listener de contexte est appelé au déploiement de l’application pour charger un contexte d’application Spring. La localisation de ce contexte est fournie par le paramètre contextConfigLocation, également déclaré dans le fichier web.xml. Ce contexte d’application Spring contient les beans de l’application; c'est la balise mère qui englobe les balises de la classe listener - Balise "<listener-class>"
on y définit la cla calsse listener à savoir "ContextLoaderListener"; - 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. - Balise <servlet-class>
nom de la classe - 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. - Balise <url-pattern>
.... - Balise <servlet-name>
Sous la balise <servlet-name> est défini le nom d'une instance de la servlet DispatcherServlet - 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 représentant 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 dans le fichier WEB-INF/web.xml le nom de notre fichier de configuration ici qui est root-context.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 scopes standards (portées standards) 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_de_la _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".
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.
- La balise <context: composant-scan ...>
permet d'activer l'analyse des annotations Spring MVC, - 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.
- ....
- ....
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 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 programmation 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:
- utilisation d'un fichier web.xml (devenu optionnel).
- utilisation d'un web-fragment.xml.
- utilisation de javax.servlet.ServletContainerInitializer.
- 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 par 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 de 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)...