FAQ SpringConsultez toutes les FAQ
Nombre d'auteurs : 5, nombre de questions : 41, dernière mise à jour : 24 avril 2008 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
- Comment configurer et utiliser un conteneur Spring ?
- Comment définir un bean ?
- Comment définir plusieurs noms pour un Bean
- Comment définir un Bean en tant que singleton ?
- Comment injecter des propriétés de type Properties
- Comment injecter un Bean dans un autre ?
- Comment injecter des dépendances via le constructeur ?
- Comment externaliser des propriétés dans un fichier Properties ?
- Comment injecter une constante statique dans une propriété ?
- Comment injecter des propriétés de types simples ?
- Comment configurer une liste ?
- Comment configurer une Map ?
- Comment fournir le context Spring à un Bean ?
- Comment effectuer des vérifications après la configuration des propriétés ?
- Comment accéder au contexte Spring depuis un composant non géré par Spring ?
- Que propose le namespace p ?
- Comment fermer un contexte d'application en détruisant les Beans ?
Afin de configurer un conteneur Spring, il est nécessaire de créer un fichier xml contenant la définition des divers Beans qui seront gérés par Spring.
Voici un exemple simple de ce fichier, version Spring 2.0 utilisant des namespaces :
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | <?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-2.0.xsd"> <bean name="unBean" class="com.developpez.spring.unBean"> <property name="unePropriete" value="Hello world"/> </bean> </beans> |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 | <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean name="unBean" class="com.developpez.spring.unBean"> <property name="unePropriete" value="Hello world"/> </bean> </beans> |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Instanciation d'un contexte Spring à partir d'un fichier XML dans le classpath ApplicationContext ap = new ClassPathXmlApplicationContext("com/developpez/spring/applicationContext.xml"); // Instanciation d'un contexte Spring à partir d'un fichier sur le disque ApplicationContext ap2 = new FileSystemXmlApplicationContext("c:\\applicationContext.xml"); // Instanciation d'un BeanFactory à partir d'un fichier xml dans le classpath Resource resource = new ClassPathResource("com/developpez/spring/beans.xml"); BeanFactory factory = new XmlBeanFactory(resource); // Instanciation d'un BeanFactory à partir d'un fichier xml sur le disque Resource resource2 = new FileSystemResource("c:\\beans.xml"); BeanFactory factory2 = new XmlBeanFactory(resource); |
Code java : | Sélectionner tout |
1 2 3 | MonBean bean = (MonBean )ap.getBean("monBean"); // ou MonBean bean2 = (MonBean) factory.getBean("monBean"); |
La définition d'un bean dans le fichier de configuration se fait comme ceci :
Code xml : | Sélectionner tout |
1 2 3 | <beans> <bean id="monBean" class="com.developpez.spring.MonBean"/> </beans> |
Il est possible de donner plusieurs noms à un Bean via l'attribut name, par exemple le bean :
Code xml : | Sélectionner tout |
1 2 3 4 5 | <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-2.0.xsd"> <bean id="monBean" class="com.developpez.spring.MonBean" name="monBeanAlias,aliasMonBean" /> </beans> |
possède le nom monBean (défini par l'ID), mais aussi monBeanAlias et aliasMonBean. Les différents noms étant séparés par une virgule.
Si rien n'est spécifié, Spring considère tout Bean comme un singleton . Autrement dit, lorsque deux demandes sont faites pour un même Bean, c'est la même instance de l'objet qui est fournie par le BeanFactory/ApplicationContext.
Si vous désirez qu'un nouvel objet soit instancié à chaque fois, il faut le spécifier dans la définition du Bean :
Code xml : | Sélectionner tout |
1 2 3 | <beans> <bean id="monBean" class="com.developpez.spring.MonBean" singleton="false"/> </beans> |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 | <!-- Bean Singleton --> <bean id="monBean" class="com.developpez.spring.MonBean" scope="singleton"/> </beans> <!-- Bean non Singleton --> <bean id="monBean" class="com.developpez.spring.MonBean" scope="prototype"/> </beans> |
Spring fournit des balises afin de pouvoir gérer facilement les propriétés de type Properties :
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | <bean id="monBean" class="com.developpez.spring.MonBean" name="monBeanAlias,aliasMonBean"> <property name="proprietes"> <props> <prop key="application.nom">Mon Application</prop> <prop key="application.version">1.0.0</prop> <prop key="application.auteur">Gildas Cuisinier</prop> </props> </property> </bean> |
Code : | Sélectionner tout |
1 2 3 | application.nom=Mon Application application.version=1.0.0 application.auteur=Gildas Cuisinier |
Afin d'illustrer l'injection de Bean dans un autre grâce à Spring partons d'un exemple.
Soit un service, qui possède entre autres une méthode pour lister les utilisateurs :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | public class UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public List listUsers(){ return userDao.listUsers(); } } |
Code java : | Sélectionner tout |
1 2 3 | public interface UserDao { public List listUsers(); } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | public class UserDaoImpl implements UserDao { public List listUsers() { List result = new ArrayList(); result.add(new User("hikage", "password")); result.add(new User("spring", "spring")); return result; } } |
Code xml : | Sélectionner tout |
<bean id="userDao" class="com.developpez.spring.UserDaoImpl"/>
Code xml : | Sélectionner tout |
1 2 3 | <bean id="userService" class="com.developpez.spring.UserService"> <property name="userDao" ref="userDao"/> </bean> |
Pour injecter des propriétés via le constructeur d'une classe, il faut utiliser les balises constructor-arg.
Soit la classe :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | public class BeanConstructor { private String chaine; private Integer entier; public BeanConstructor(String chaine, Integer entier) { this.chaine = chaine; this.entier = entier; } } |
Code xml : | Sélectionner tout |
1 2 3 4 | <bean id="beanConstructeur2" class="com.developpez.hikage.BeanConstructor"> <constructor-arg index="0" value="Test"/> <constructor-arg index="1" value="23"/> </bean> |
Code java : | Sélectionner tout |
public BeanConstructor(String chaine, String chaine2)
Code xml : | Sélectionner tout |
1 2 3 4 | <bean id="beanConstructeur" class="com.developpez.hikage.BeanConstructor"> <constructor-arg type="java.lang.String" value="Test"/> <constructor-arg type="java.lang.Integer" value="23"/> </bean> |
Soit un fichier properties qui contient les informations suivantes :
Code : | Sélectionner tout |
1 2 3 4 | datasource.driver=org.mysql.driver.Driver datasource.url=jdbc://mysql:localhost/maBase datasource.username=dbUser datasource.password=dbPassword |
Code xml : | Sélectionner tout |
1 2 3 4 5 | <bean name="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:com/developpez/hikage/properties/datasource.properties</value> </property> </bean> |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 | <bean id="datasource" class="com.developpez.hikage.Datasource"> <property name="urlConnection" value="${datasource.url}"/> <property name="drivers" value="${datasource.drivers}"/> <property name="username" value="${datasource.username}"/> <property name="password" value="${datasource.password}"/> </bean> |
Les informations nécessaires à la configuration sont parfois stockées dans des champs statiques d'une classe ou d'une interface. Spring fournit une classe utilitaire pour récupérer ces informations pour ainsi les injecter dans un bean.
Par exemple, le nom d'une application est stocké dans une classe Constants :
Code java : | Sélectionner tout |
1 2 3 | public class Constants { public static final String APPLICATION_NAME = "FAQ Spring"; } |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 | <bean id="applicationInformation" class="com.developpez.spring.ApplicationInformation"> <property name="applicationName"> <bean class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField" value="com.developpez.spring.Constants.APPLICATION_NAME"/> </bean> </property> </bean> |
Code xml : | Sélectionner tout |
1 2 3 4 5 | <bean id="applicationInformationV2" class="com.developpez.spring.ApplicationInformation"> <property name="applicationName"> <util:constant static-field="com.developpez.spring.Constants.APPLICATION_NAME"/> </property> </bean> |
Soit la classe :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class MonBean { private String chaine; private Integer entier; private Long entierLong; private Boolean booleen; private Float flottant; public void setChaine(String chaine) { this.chaine = chaine ; } public String getChaine() { return this.chaine ; } public void setEntier(Integer entier) { this.entier = entier ; } public Integer getEntier() { return this.entier ; } public void setEntierLong(Long entierLong) { this.entierLong = entierLong ; } public String getEntierLong() { return this.entierLong ; } public void setBooleen( Boolean booleen ) { this.booleen = booleen ; } public Boolean getBooleen() { return this.booleen; } public void setFlottant(Float flottant) { this.flottant = flottant ; } public Float getFlottant() { return this.flottant } ; } |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <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-2.0.xsd"> <bean id="monBean" class="com.developpez.spring.MonBean"> <property name="chaine" value="Visitez Developpez.com"/> <property name="booleen" value="true"/> <property name="entier" value="10"/> <property name="flottant" value="10.3"/> <property name="entierLong" value="204"/> </bean> </beans> |
Soit la classe :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | public class BeanList { private List list; public List getList() { return list; } public void setList(List list) { this.list = list; } } |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | <bean id="beanList" class="com.developpez.hikage.BeanList"> <property name="list"> <list> <value>Valeur 1</value> <value>Valeur 2</value> <value>Valeur 3</value> <ref bean="monBean"/> </list> </property> </bean> |
Soit une classe :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | public class BeanMap { private Map map; public Map getMap() { return map;} public void setMap(Map map) { this.map = map; } } |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <bean id="beanMap" class="com.developpez.hikage.BeanMap"> <property name="map"> <map> <entry> <key><value>Clé de type String</value></key> <value>Valeur associé de type String</value> </entry> <entry> <!-- Clé de type Object --> <key><ref bean="monBeanCle"></ref></key> <!-- Valeur dde type Object --> <ref bean="monBeanValeur"></ref> </entry> </map> </property> </bean> |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 | <bean id="beanMap" class="com.developpez.hikage.BeanMap"> <property name="map"> <map> <entry key="Ma clé de type String" value="Valeur associée de type String" /> <entry key-ref="monBean" value-ref="monBean"/> </map> </property> </bean> |
Il est parfois nécessaire à un Bean de posséder une référence à l'ApplicationContext (ou le BeanFactory) qui s'occupe de son cycle de vie. Pour cela, il suffit que celui-ci implémente une de ces deux interfaces pour que Spring injecte automatiquement la référence correspondante :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 | public interface ApplicationContextAware { void setApplicationContext(org.springframework.context.ApplicationContext applicationContext) throws org.springframework.beans.BeansException; } public interface BeanFactoryAware { void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory) throws org.springframework.beans.BeansException; } |
Dans le cas de l'injection de dépendances par accesseurs, il n'est pas possible de manière standard de vérifier que tous les arguments obligatoires sont fournis. De plus, il est parfois nécessaire d'effectuer certaines opérations de configuration manuellement. Pour cela, Spring fournit une interface :
Code xml : | Sélectionner tout |
1 2 3 4 | public interface InitializingBean { void afterPropertiesSet() throws java.lang.Exception; } |
Pour donner accès au contexte Spring aux composants non gérés par Spring, il suffit d'implémenter un bean géré par Spring, implémentant ApplicationContextAware, qui va exposer des méthodes d'accès au contexte Spring.
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class ApplicationContextHolder implements ApplicationContextAware { /** Contexte Spring qui sera injecté par Spring directement */ private static ApplicationContext context = null; /** * Méthode de ApplicationContextAware, qui sera appelée automatiquement par le conteneur */ public void setApplicationContext(ApplicationContext ctx) throws BeansException { context = ctx; } /** * Méthode statique pour récupérer le contexte */ public static ApplicationContext getContext() { return context; } } |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | <?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-2.5.xsd"> <!-- ============================== BEANS ============================= --> <!-- Bean d'acces au Contexte --> <bean id="applicationContextHolder" class="com.developpez.spring.ApplicationContextHolder" /> <!-- Definition des autres beans --> </beans> |
Le setteur de la classe va stocker ce contexte dans une variable de classe (variable déclarée statique). Et la classe propose une méthode, statique, de récupération de ce contexte.
Exemple d'utilisation :
Code java : | Sélectionner tout |
1 2 | ApplicationContext context = ApplicationContextHolder.getContext(); MonBean bean = (MonBean) context.getBean("monBean"); |
Le namespace p a pour but de réduire la taille du fichier de configuration de Spring, en proposant des raccourcis pour la définition des propriétés.
Par exemple, un fichier de configuration sans le namespace p :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <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-2.5.xsd"> <bean name="monBean" class="com.developpez.spring.Personne"> <property name="nom" value="Cuisinier"/> <property name="prenom" value="Gildas"/> <property name="age" value="23"/> <property name="pays" value="Belgique"/> <property name="parrain" ref="beanParrain"/> </bean> <bean name="beanParrain" class="com.developpez.spring.Personne"/> </beans> |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean name="monBean" class="com.developpez.spring.Personne" p:nom="Cuisinier" p:prenom="Gildas" p:age="23" p:pays="Belgique" p:parrain-ref="beanParrain"/> </bean> <bean name="beanParrain" class="com.developpez.spring.Personne"/> </beans> |
Lors de l'utilisation de Spring en dehors d'un contexte Web, il est intéressant de fermer proprement un contexte d'application, en libérant les ressources et les beans.
La méthode close() de l'interface ConfigurableApplicationContext permet de faire cela. Il faut donc que l'implémentation du contexte d'application Spring implémente cette interface, et heureusement c'est le cas de ClasspathXmlApplicationContext, qui est sans doute la version la plus utilisée.
Code java : | Sélectionner tout |
1 2 3 4 | ConfigurableApplicationContext context = new ClasspathApplicationContext("com/developpez/hikage/context/applicationContext.xml"); // Termine le contexte Spring context.close(); |
Une autre méthode de ConfigurableApplicationContext qui peut s'avérer utile est registerShutdownHook(). Cette méthode permet de spécifier à la JVM de fermer automatiquement le contexte Spring lorsque l'application s'arrête.
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.