4 Le conteneur léger de Spring
Maintenant que nous avons étudié les principes de base des conteneurs légers, nous allons à présent voir comment Spring les met en pratique.
4.1 La fabrique de beans
La fabrique de beans constitue l'interface de base de Spring pour accéder aux fonctionnalités de son conteneur léger. Par interface de base, nous entendons interface disposant des fonctionnalités minimales de manipulation du conteneur d'IoC.
La fabrique de beans se manipule par le biais de deux interfaces, BeanFactory et BeanDefinitionRegistry.
4.1.2 L'interface BeanFactory
Son but est de gérer l'accès aux beans définis dans le référentiel des beans. Les méthodes qu'elle propose permettent uniquement l'accès à ces beans. Le code de cette interface est reproduit ci-dessous:
// Imports
public interface BeanFactory
{
public abstract Object getBean(String beanName)
throws BeansException;
public abstract Object getBean(String beanName,
Class beanType)
throws BeansException;
public abstract boolean containsBean(String beanName);
public abstract boolean isSingleton(String beanName)
throws NoSuchBeanDefinitionException;
public abstract Class getType(String beanName)
throws NoSuchBeanDefinitionException;
public abstract String[] getAliases(String beanName)
throws NoSuchBeanDefinitionException;
}
La méthode getBean(String beanName) permet de récupérer un bean à partir du nom qui lui est associé dans le référentiel.
La méthode getBean(String beanName, Class beanType) permet en plus de spécifier le type du bean à récupérer.
La méthode containsBean(String beanName) permet de savoir si le conteneur léger contient le bean correspondant au nom passé en paramètre.
La méthode isSingleton(String beanName) permet de savoir si un bean est un singleton ou un prototype.
La méthode getType(String beanName) permet de récupérer le type du bean correspondant au paramètre.
La méthode getAliases(String beanName) permet de récupérer les différents alias pour un bean, Spring permettant de spécifier plusieurs noms pour un bean.
Cette interface propose les méthodes de base pour manipuler les beans au sein du conteneur. Spring fournit plusieurs autres interfaces étendant celle-ci de manière à offrir des fonctionnalités supplémentaires. Nous pouvons par exemple citer:
l'interface ListableBeanFactory qui offre des fonctions avancées de manipulation des beans
l'interface HierarchicalBeanFactory qui propose de hiérarchiser les fabriques de beans
4.1.3 L'interface BeanDefinitionRegistry
Autant l'interface BeanFactory permet d'accéder aux beans du conteneur, autant elle ne permet pas de d'indiquer à ce dernier les dépendances qu'il doit gérer. C'est le rôle de l'interface BeanDefinitionRegistry. Son code est reproduit ci-dessous:
// Imports
public interface BeanDefinitionRegistry
{
public abstract int getBeanDefinitionCount();
public abstract String[] getBeanDefinitionNames();
public abstract boolean containsBeanDefinition(String beanName);
public abstract BeanDefinition getBeanDefinition(String beanName)
throws NoSuchBeanDefinitionException;
public abstract void registerBeanDefinition(String beanName,
BeanDefinition beanDef)
throws BeansException;
public abstract String[] getAliases(String beanName)
throws NoSuchBeanDefinitionException;
public abstract void registerAlias(String beanName,
String beanAlias)
throws BeansException;
}
La méthode getBeanDefinitionCount() permet de récupérer le nombre de beans déclarés dans le conteneur.
La méthode getBeanDefinitionNames() permet de récupérer l'ensemble des identifiants des beans gérés par le conteneur.
La méthode containsBeanDefinition(String beanName) permet de savoir si une définition existe pour le nom passé en paramètre.
La méthode getBeanDefinition(String beanName) permet de récupérer la définition d'un bean.
La méthode registerBeanDefinition(String beanName, BeanDefinition beanDef) permet d'enregistrer un bean au sein du conteneur.
La méthode getAliases(String beanName) permet de récupérer les différents alias pour un bean.
La méthode registerAlias(String beanName, String beanAlias) permet d'ajouter un alias pour un bean.
4.1.4 Implémentation de ces interfaces
Les deux interfaces précédemment décrites permettent d'interagir avec le conteneur. Spring fournit plusieurs classes implémentant ces dernières et répondant chacune à un besoin particulier.
Une implémentation simple est la classe DefaultListableBeanFactory disponible au sein du package org.springframework.beans.factory.support. Elle se contente de fournir simplement un accès au conteneur via les deux interfaces décrites ci-dessus.
La classe XmlBeanFactory du package org.springframework.beans.factory.xml est plus évoluée en ce sens qu'elle permet de définir le référentiel de beans par le biais d'un fichier XML. Pour cela, Spring fournit ses propres balises XML pour la définition des beans. Le schéma XML est disponible à l'adresse suivante:
http://www.springframework.org/schema/beans/spring-beans.xsd
4.2 Le contexte d'applications
Outre la de fabrique de beans, Spring propose la notion de contexte d'applications qui englobe la fabrique et propose des fonctionnalités supplémentaires mais sans rapport avec le concept de conteneur léger. Parmi ces fonctionnalités, on peut citer:
la hiérarchisation des contextes pour par exemple isoler les beans d'une couche afin qu'ils ne soient pas visibles depuis les autres couches
la gestion des messages de l'application et leur internationalisation
le chargement de ressources depuis le système de fichier, le classpath de l'application, le web, ...
...
De même que les interfaces BeanFactory et BeanDefinitionRegistry possèdent leur propres implémentations, l'interface ApplicationContext a les siennes. Ainsi, le développeur a le choix de l'implémentation correspondant le mieux aux besoins de l'application.
Parmi les plus répandues, on distingue les classes FileSystemXmlApplicationContext et ClassPathXmlApplicationContext qui correspondent à la classe XmlBeanFactory évoquée ci-avant. Elles permettent de charger le référentiel du conteneur de Spring soit depuis le système de fichiers, soit depuis le classpath de l'application.
Par convention, le fichier XML contenant les définitions des beans est appelé applicationContext.xml. Si l'application doit comporter plusieurs fichiers de définition, par exemple un fichier par couche applicative, ceux-ci seront nommés applicationContext-<nom>.xml. Cette convention de nommage n'est pas impérative, il est évidemment possible d'utiliser un nom totalement arbitraire.
4.3 Définition des beans au sein du conteneur
Note: par la suite, nous allons nous concentrer sur la configuration du conteneur par fichier XML plus courante et plus commode que la manière programmatique.
Pour définir un bean au sein du conteneur, deux informations sont obligatoires:
le nom du bean
le type du bean pleinement qualifié
4.3.1 Structure du fichier XML
La balise racine du fichier de définition des beans est la balise beans.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Définitions -->
</beans>
Pour définir un bean, la syntaxe est la suivante:
class="com.casteran.samples.ABean" />
où l'attribut id spécifie le nom du bean et l'attribut class le type du bean.
Pour ajouter un ou des alias pour le bean, il convient d'utiliser l'attribut name.
class="com.casteran.samples.ABean"
name="alias1,alias2" />
Les alias peuvent être séparés soit par une virgule, soit par un espace.
Pour spécifier que le bean défini doit être un singleton, il faut positionner l'attribut singleton à true. Par défaut, il est positionné à false, un bean est donc par défaut un prototype.
class="com.casteran.samples.ABean"
name="alias1,alias2"
singleton="true" />
Après avoir défini les beans, l'étape suivante consiste à initialiser leurs propriétés en utilisant l'injection de dépendances, soit par constructeur, soit par modificateurs. Les deux parties suivantes décrivent ces méthodes.
4.3.1.1 L'injection par constructeur
Prenons les deux classes suivantes pour illustrer l'injection de dépendances par constructeur:
public class ABean {
// ...
}
public class AnotherBean {
private String aString;
private ABean aBean;
// ...
public AnotherBean(String aString, ABean aBean) {
this.aString = aString;
this.aBean = aBean;
}
// ...
}
La classe nécessitant une dépendance, en l'occurrence AnotherBean, doit disposer d'un constructeur permettant d'initialiser la dépendance.
La définition dans le référentiel se fait de la manière suivante:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="aBean"
class="com.casteran.samples.ABean" />
<bean id="anotherBean"
class="com.casteran.samples.AnotherBean">
<constructor-arg>
<value>
Bean description
</value>
</constructor-arg>
<constructor-arg>
<ref bean="aBean" />
</constructor-arg>
</bean>
</beans>
Le bean anotherBean peut également être défini de la manière simplifiée suivante:
class="com.casteran.samples.AnotherBean">
<constructor-arg value="Bean description" />
<constructor-arg ref="aBean" />
</bean>
Le tag ou attribut ref (suivant la forme utilisée) fait référence à un autre bean géré par Spring.
4.3.1.2 L'injection par accesseurs
Prenons les deux classes suivantes pour illustrer l'injection de dépendances par modificateurs:
public class ABean {
// ...
}
public class AnotherBean {
private String aString;
private ABean aBean;
// ...
public void setAString(String aString) {
this.aString = aString;
}
public void setABean(ABean aBean) {
this.aBean = aBean;
}
// ...
}
La classe nécessitant une dépendance, en l'occurrence AnotherBean, doit disposer d'un setter permettant d'initialiser la dépendance.
La définition dans le référentiel se fait de la manière suivante:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="aBean"
class="com.casteran.samples.ABean" />
<bean id="anotherBean"
class="com.casteran.samples.AnotherBean">
<property name="aString">
<value>
Bean description
</value>
</property>
<property name="aBean">
<ref bean="aBean" />
</property>
</bean>
</beans>
L'attribut name de la balise property correspond au nom de la variable de classe initialisée.
La balise property peut également être écrite sous la forme simplifiée suivante:
<property name="String" ref="aBean" />
Le tag ou attribut ref (suivant la forme utilisée) fait référence à un autre bean géré par Spring.
Que ce soit dans le cas de l'injection par constructeur ou par accesseurs, un bean déclaré dans le conteneur et utilisé par d'autres beans est appelé collaborateur.
Spring permet d'injecter en tant que dépendances un grand nombre de types de données que nous allons détailler ci-dessous.
4.3.1.3 Les types simples
Les types simples que Spring gère sont les suivants, qu'ils soient scalaires ou objet:
les nombres: int, long, float, java.lang.Integer, java.lang.Long, ...
les caractères: char, java.lang.Character
les chaînes de caractères et tableaux de chaînes de caractères: String, String[]
les booléens: boolean, java.lang.Boolean
les tableaux de bytes: byte[]
les propriétés: java.util.Properties
les locales: java.util.Locale
les URLs: java.net.URL
les fichiers: java.io.File
les classes
la valeur null
L'exemple ci-dessous montre l'injection de tous ces types pour un bean. La forme retenue pour la définition des propriétés du bean est la version simplifiée.
// Imports
public class SampleBean {
private Integer anInteger;
private char aChar;
private Character aCharacter;
private String aString;
private String[] aStringArray;
private Boolean aBoolean;
private byte[] aByteArray;
private Properties someProperties;
private Locale aLocale;
private URL anURL;
private File aFile;
private Class aClass;
private Object aNullValue;
// Setters
}
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean">
<property name="anInteger"
value="45" />
<property name="aChar"
value="a" />
<property name="aCharacter"
value="z" />
<property name="aString"
value="qwerty" />
<property name="aStringArray"
value="azerty,qwerty" />
<property name="aBool"
value="true" />
<property name="aBoolean"
value="false" />
<property name="aByteArray"
value="a byte array" />
<property name="someProperties"
value="key1=value1\nkey2=value2" />
<property name="aLocale"
value="en_US" />
<property name="anURL"
value="http://www.google.fr/" />
<property name="aFile"
value="file:/home/reno/file.txt" />
<property name="aClass"
value="java.text.SimpleDateFormat" />
<property name="aNullValue">
<null />
</property>
</bean>
</beans>
Spring va s'occuper de convertir les chaînes de caractères contenues dans le fichier XML vers le type scalaire ou Java correspondant.
4.3.1.4 Les types structurés
Les types de données structurés supportés pour l'injection de dépendances sont:
les listes: java.util.List
les sets: java.util.Set
les maps: java.util.Map
Le fichier XML ci-dessous montre comment initialiser ces types:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean">
<property name="aList">
<list>
<value>item1</value>
<value>item2</value>
</list>
</property>
<property name="aSet">
<set>
<value>item1</value>
<value>item2</value>
</set>
</property>
<property name="aMap">
<map>
<entry key="key1" value="value1" />
<entry key="key2">
<value>value2</value>
</entry>
</map>
</property>
</bean>
</beans>
Les valeurs contenues dans une liste, un set ou une map peuvent être des beans gérés par le conteneur léger. Dans ce cas, au lieu d'utiliser la balise <value />, nous utilisons la balise <ref/> dont l'attribut bean doit contenir le nom du bean adéquat.
4.3.1.5 Les collaborateurs
Comme nous l'avons évoqué précédemment, Spring permet d'injecter dans un bean d'autres beans, qui sont dans ce cas dénommés collaborateurs. L'injection d'un collaborateur peut se faire de manière explicite comme vu dans les exemples précédents. Mais Spring permet aussi d'injecter les collaborateurs implicitement. Cette injection est appelée en anglais autowiring ou remplissage automatique.
Il existe plusieurs types d'autowiring:
l'autowiring par nom: byName. Spring se base sur le nom de la variable de classe pour charger le bean correspondant.
l'autowiring par type: byType. Spring va chercher un bean ayant le même type que la variable de classe à initialiser. Dans le cas où plusieurs beans sont du type demandé, Spring lève une exception. Dans le cas où aucun bean n'est trouvé, Spring initialise la variable à null.
l'autowiring par constructeur: constructor.Spring se base sur les paramètres du constructeur pour chercher les beans correspondants.
l'autowiring par détection: autodetect. Spring va utiliser de lui-même la recherche par type ou par constructeur. Si la classe n'a qu'un constructeur par défaut (sans paramètres), c'est l'autowiring par type qui est choisi.
La syntaxe pour l'autowiring est présentée ci-dessous:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean"
autowire="byName | byType | constructor | autodetect" />
</bean>
</beans>
4.4 Cycle de vie des beans
Chaque bean de Spring a une « naissance » et une « mort ». La naissance d'un bean survient par défaut au démarrage du conteneur. Ce comportement par défaut peut être surchargé en positionnant l'attribut lazy-init du tag bean à true pour spécifier de charger le bean au runtime. La syntaxe est présentée ci-dessous:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean"
lazy-init="true" />
</bean>
</beans>
La mort du bean ne survient pas au même moment selon la nature du bean. Si c'est un prototype, le bean sera détruit quand il n'y aura plus besoin de l'injecter et que le garbage collector aura été déclenché. Spring n'a donc pas de moyen de savoir quand meurt un prototype.
Si c'est un singleton, Spring va lui-même se charger de sa destruction et ainsi pouvoir déclencher des traitements si nécessaire.
4.4.1 Traitements à la naissance d'un bean
4.4.1.1 L'attribut init
Cet attribut est défini dans le fichier XML référençant les beans de l'application. La valeur qu'il accepte est le nom d'une méthode du bean en question. Cette méthode ne doit pas avoir de paramètres et ne doit pas comporter de type de retour. Vous trouverez ci-dessous un exemple d'utilisation de cette méthode:
Classe Java
public class SampleBean {
// ...
public void initializeSampleBean() {
// processing
}
// ...
}
Référentiel de dépendances:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean"
init="initializeSampleBean">
<!-- ... -->
</bean>
</beans>
4.4.1.2 L'interface InitializingBean
Cette solution implique que la classe représentant le bean implémente l'interface InitializingBean du package org.springframework.beans.factory. Cette interface impose de définir la méthode afterPropertiesSet(). Cette méthode n'accepte pas de paramètres et ne renvoie pas de valeur. Le code ci-dessous illustre ce principe:
Classe Java:
// imports
public class SampleBean implements InitializingBean {
// ...
public void afterPropertiesSet() {
// processing
}
// ...
}
Référentiel de dépendances:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean">
<!-- ... -->
</bean>
</beans>
Nous ne spécifions plus quelle méthode doit être appelée à la création du bean.
A noter que la première solution est préférable à l'utilisation de cette interface car cette dernière crée un couplage entre l'application et l'API de Spring.
4.4.2 Traitements à la mort d'un singleton
Spring ne peut appliquer de traitements à la mort d'un bean que si celui-ci est un singleton, c'est-à-dire que sa destruction est assurée par le conteneur léger. Dans le cas d'un prototype, la mort du bean est à la charge du garbage collector et aucun mécanisme n'existe pour avertir Spring des destructions d'objets effectuées.
4.4.2.1 L'attribut destroy-method
Cet attribut est défini dans le fichier XML référençant les beans de l'application. La valeur qu'il accepte est le nom d'une méthode du bean en question. Cette méthode ne doit pas avoir de paramètres et ne doit pas comporter de type de retour. Vous trouverez ci-dessous un exemple d'utilisation de cette méthode:
Classe Java:
public class SampleBean {
// ...
public void destroySampleBean() {
// processing
}
// ...
}
Référentiel de dépendances:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean"
destroy-method="destroySampleBean">
<!-- ... -->
</bean>
</beans>
4.4.2.2 L'interface DisposableBean
Cette solution implique que la classe représentant le bean implémente l'interface DisposableBean du package org.springframework.beans.factory. Cette interface impose de définir la méthode destroy(). Cette méthode n'accepte pas de paramètres et ne renvoie pas de valeur. Le code ci-dessous illustre ce principe:
Classe Java:
// imports
public class SampleBean implements InitializingBean {
// ...
public void destroy() {
// processing
}
// ...
}
Référentiel de dépendances:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleBean"
class="com.casteran.samples.SampleBean">
<!-- ... -->
</bean>
</beans>
Notez que nous ne spécifions plus quelle méthode doit être appelée à la destruction du bean.
Pour les mêmes raisons que pour l'exécution de traitements à la naissance d'un bean, il est plus judicieux d'utiliser la première solution.
4.5 Fonctionnalités avancées du contexte d'applications
Comme nous l'avons vu, le contexte d'applications de Spring est une fabrique évoluée proposant, outre la gestion des beans, certaines fonctionnalités sans rapport avec le principe de conteneur léger. Nous allons étudier les principales.
4.5.1 L'internationalisation
Traditionnellement, la localisation d'une application Java se fait au travers de fichiers de propriétés composés de paires de clés / valeurs. Ces fichiers sont nommés sous la forme suivante:
<nom_fichier>_<code_ISO_pays>.properties
Ainsi, pour la France, le nom du fichier serait par exemple:
myApplicationMessages_FR.properties
Un fichier sans code ISO est considéré comme le fichier contenant les messages de la langue par défaut de l'application.
Le contenu d'un fichier se présente sous la forme suivante:
my_application.welcome = Bienvenue {0}
{0} correspond à une variable dont la valeur sera passée en paramètre dans la méthode de récupération du message. Il est possible d'en mettre autant que l'on veut.
Spring permet d'accéder à ces paires de clés / valeurs au sein de son conteneur léger. La classe org.springframework.context.support.ResourceBundleMessageSource permet de concaténer plusieurs fichiers de propriétés pour une langue (par exemple, un fichier pourrait contenir les messages utilisés par la couche présentation et un autre les messages d'erreur). La propriété basenames contient la liste des différents fichiers de propriétés utilisés par l'application. Pour cela, il faut définir cette classe en tant que bean de la manière suivante:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>applicationMessages</value>
<value>errorMessages</value>
</list>
</property>
</bean>
</beans>
Spring va donc charger les fichiers applicationMessages_FR.properties et errorMessages_FR.properties si l'application est en français.
L'accès aux messages depuis l'application se fait grâce à la méthode getMessage() comme décrit ci-dessous:
public void aVoid(User aUser)
throws NoSuchMessageException {
ApplicationContext appCtx =
new ClassPathXmlApplicationContext("applicationContext.xml");
String welcomeMsg =
appCtx.getMessage("my_application.welcome",
new String[] {aUser.getFullName()},
Locale.FRANCE);
}
}
Le premier paramètre de la méthode est le nom de la clé.
Le second est un tableau d'Object contenant les éventuels paramètres de la clé. Si la clé ne comporte pas de paramètre, cet argument doit être mis à null.
Le dernier paramètre est la locale pour laquelle on souhaite récupérer le message. Cet argument doit être du type java.util.Locale. Spring va aller chercher dans les fichiers de messages dont le code ISO correspond à la locale. Si ce paramètre est égal à null, les fichiers par défaut (dont le nom ne comporte pas de code ISO) seront utilisés.
Cette méthode lève l'exception org.springframework.context.NoSuchMessageException si aucune clé ne correpond à celle demandée.
4.5.2 Le chargement de ressources
Une ressource est un fichier externe qu'utilise l'application. Cette ressource peut être disponible sur différents supports:
le système de fichiers local,
le protocole HTTP,
le classpath de l'application, ...
Selon le support, la méthode d'accès diffère, Java ne proposant pas de mécanisme générique d'accès aux ressources. Ainsi, pour récupérer un fichier sur le système de fichiers, nous utiliserons un objet de type java.io.File, tandis qu'un fichier publié sur un site Internet sera manipulé par un objet de type java.net.URL.
Spring permet d'abstraire le support de stockage des ressources et utilise les notions de ressource et de chargeur de ressources, représentées chacune par une interface:
org.springframework.core.io.Resource définit les ressources
org.springframework.core.io.ResourceLoader représente les chargeurs de ressources
Plusieurs implémentations de l'interface Resource sont fournies par Spring:
FileSystemResource,
ClassPathResource,
UrlResource,
InputStreamResource,
ByteArrayResource, ...
Le chargeur de ressources est disponible via les contextes d'applications disposant de la méthode getResource() définie par l'interface ResourceLoader. Cette méthode accepte un paramètre contenant le chemin relatif ou absolu d'accès au fichier. Si un chemin absolu est spécifié, il doit être au format URL. Pour qu'un bean puisse accéder à des ressources, il doit implémenter l'interface org.springframework.context.ResourceLoaderAware. Celle-ci propose la méthode setResourceLoader(ResourceLoader loader) qui permet au conteneur léger d'injecter un chargeur de ressources au bean. Une fois la ressource récupérée, le fichier correspondant est disponible par le biais des méthodes getFile() et getURL() selon le support.
Voici un exemple de chargement de ressources par le contexte d'applications:
private ResourceLoader resourceLoader;
// ...
public setResourceLoader(ResourceLoader resourceloader) {
this.resourceLoader = resourceloader;
}
// ...
public void processingResources() {
ApplicationContext appCtx =
new ClassPathXmlApplicationContext("applicationContext.xml");
Resource fsResource =
appCtx.getResource("file://home//rcasteran//Documents//data.txt");
Resource webResource =
appCtx.getResource("http://www.casteran.com/data.html");
Resource classPathResource =
appCtx.getResource("classpath:com/casteran/samples/data.txt");
// Processing resources
File fsFile = fsResource.getFile();
File cpFile = classPathResource.getFile();
URL webFile = webResource.getURL();
// ...
}
// ...
}

Comments
Post new comment