Projets
Pages enfant
  • 1.7 Les beans Spring

Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.
Commentaire: Migrated to Confluence 5.3
Astuce
titleRelu

Relecture RB faite le

Balise Wiki
{tip:title=Relu}Relecture RB faite le

16/02/2011

{tip}

Ce

...

chapitre

...

n'a

...

pas

...

la

...

prétention

...

d'être

...

une

...

formation

...

à

...

Spring

...

.

...

Pour

...

plus

...

d'informations,

...

vous

...

pouvez

...

vous

...

reporter

...

à

...

la

...

documentation

...

de

...

springsource

...

(

...

HTML

...

/

...

PDF

...

).

...

Ne

...

sont

...

abordés

...

ici

...

que

...

quelques

...

détails

...

permettant

...

de

...

mieux

...

comprendre

...

certains

...

éléments

...

des

...

fichiers

...

de configuration de esup-commons

...

.

Remarque
{note}{_}

Esup-commons

V2

_

utilise

Spring

3

{note}

Tout

...

au

...

long

...

de

...

ce

...

chapitre

...

nous

...

allons

...

nous

...

appuyer

...

sur

...

un

...

exemple

...

(configuration

...

du

...

gestionnaire

...

d'exceptions) :

Bloc de code
 :
\\
{code}
<bean id="exceptionServiceFactory"
      class="org.esupportail.commons.services.exceptionHandling.CachingEmailExceptionServiceFactoryImpl"
      parent="abstractApplicationAwareBean">
   <property name="smtpService" ref="smtpService" />
   <property name="recipientEmail" value="${exceptionHandling.email}" />
   <property name="exceptionViews">
      <map>
         <entry key="java.lang.Exception" value="go_exception" />
      </map>
   </property>
   <property name="logLevel" value="${exceptionHandling.logLevel}" />
   <property name="cacheManager" ref="cacheManager" />
   <property name="cacheName" value="" />
</bean>
{code}
----
h4. Sommaire :
{toc:maxLevel=3}
----
h2. Les fichiers de configuration

_Spring_ permet de créer des objets (appelés alors _beans_) en les déclarant dans un fichier de configuration _XML_.

Le fichier de configuration principal (*

...

Sommaire :

Sommaire
maxLevel3

...

Les fichiers de configuration

Spring permet de créer des objets (appelés alors beans) en les déclarant dans un fichier de configuration XML.

Le fichier de configuration principal (properties/applicationContext.xml

...

)

...

est

...

déclaré

...

dans

...

le

...

*web.xml

...

*

...

sous

...

la

...

forme

...

d'un

...

paramètre

...

de

...

l'application

...

:

{
Bloc de code
}
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:/properties/applicationContext.xml</param-value>
</context-param>
{code}

Dans _

Dans esup-commons

...

ce

...

fichier

...

de

...

configuration

...

principal

...

contient

...

seulement

...

des

...

inclusions

...

de

...

fichiers

...

de

...

configuration

...

spécialisés

...

par

...

domaine,

...

comme

...

par

...

exemple:

{
Bloc de code
}
<import resource="exceptionHandling/exceptionHandling.xml" />
{code}

Il

...

est

...

possible,

...

suivant

...

les

...

besoins

...

de

...

votre

...

application,

...

de

...

supprimer

...

ou

...

d'ajouter

...

des

...

fichiers

...

de

...

configuration

...

spécialisés.

...

L'injection

...

de

...

données

...

Une

...

des

...

caractéristiques

...

de

...

base

...

de

...

Spring

...

est

...

de

...

permettre

...

l'injection

...

de

...

données.

{
Remarque
}

Cette

fonctionnalité

est

aussi

possible

avec

_

JSF

_

,

qui

est

également

utilisé

dans

_

esup-commons

_

,

mais

_

JSF

_

est

moins

puissant

que

_

Spring

_

dans

ce

domaine.

_

esup-commons

_

n'utilise

donc

pas

l'injection

de

données

de

_

JSF

_

.

{note}

L'injection

...

de

...

données

...

permet

...

de

...

renseigner

...

des

...

attributs

...

d'un

...

bean

...

via

...

un

...

fichier

...

de

...

configuration.

...

Le

...

bean

...

doit

...

disposer

...

d'un

...

setter

...

pour

...

l'accès

...

à

...

ces

...

attributs.

...

Voyons

...

quelques

...

exemples...

...

Injection

...

d'une

...

chaîne

...

de

...

caractères

{
Bloc de code
}
<property name="recipientEmail" value="webmaster@domain.edu"/>
{code}

Dans

...

ce

...

cas,

...

la

...

méthode

...

setRecipentEmail()

...

sera

...

appelée

...

avec

...

pour

...

paramètre,

...

la

...

valeur

...

webmaster@domain.edu

...

.

...

Injection

...

d'un

...

autre

...

bean

{
Bloc de code
}
<property name="authenticationService" ref="authenticationService"/>
{code}

On

...

voit

...

ici

...

un

...

autre

...

aspect

...

important

...

de

...

Spring

...

qui

...

est

...

l'utilisation

...

quasi

...

systématique

...

des

...

interfaces.

...

La

...

classe

...

CachingEmailExceptionServiceFactoryImpl

...

(qui

...

correspond

...

au

...

bean

...

exceptionServiceFactory

...

et

...

contient

...

la

...

définition

...

de

...

cette

...

propriété

...

authenticationService

...

)

...

a

...

un

...

attribut

...

authenticationService

...

de

...

type

...

AuthenticationService

...

.

...

AuthenticationService

...

est

...

une

...

interface.

...

Le

...

bean

...

authenticationService

...

doit

...

donc

...

être

...

d'une

...

classe

...

qui

...

implémente

...

cette

...

interface.

...

Ceci

...

permet

...

d'avoir

...

plusieurs

...

implémentations

...

possibles

...

pour

...

cette

...

interface

...

et

...

de

...

choisir,

...

simplement

...

en

...

modifiant

...

un

...

fichier

...

de

...

configuration,

...

laquelle

...

on

...

utilise.

...

Cette

...

approche

...

est

...

particulièrement

...

intéressante

...

:

...

elle

...

permet,

...

par

...

exemple,

...

de

...

très

...

facilement

...

tester

...

une

...

couche

...

de

...

l'application

...

en

...

branchant

...

des

...

implémentations

...

de

...

tests

...

des

...

autres

...

couches

...

avec

...

lesquelles

...

le

...

bean

...

doit

...

interagir.

...

Injection

...

d'une

...

map

{
Bloc de code
}
<property name="exceptionViews">
  <map>
    <entry key="java.lang.Exception" value="go_exception" />
  </map>
</property>
{code}

h3. Injection 

Injection d'une

...

liste

{
Bloc de code
}
<property name="servers">
  <list>
    <ref bean="smtpServer1" />
    <ref bean="smtpServer2" />
  </list>
</property>
{code}

h2. Utilisation de paramètres

Afin de centraliser la configuration, une bonne pratique consiste à utiliser un fichier de configuration regroupant les paramètres de 

Utilisation de paramètres

Afin de centraliser la configuration, une bonne pratique consiste à utiliser un fichier de configuration regroupant les paramètres de l'application.

...

Ceci

...

évite

...

notamment

...

de

...

devoir

...

modifier

...

n

...

fichiers

...

différents.

...

Exemple

...

d'utilisation

...

:

{
Bloc de code
}
<property name="recipientEmail" value="${exceptionHandling.email}" />
{code}

Ici

...

la

...

propriété

...

recipientEmail

...

contiendra

...

la

...

valeur

...

contenue

...

dans

...

le

...

paramètre

...

exceptionHandling.email

...

.

...

Le

...

paramètre

...

exceptionHandling.email

...

est

...

défini

...

dans

...

le

...

fichier

...

default.properties

...

et

...

peut

...

être

...

surchargé

...

dans

...

le

...

fichier

...

config.properties

...

:

{
Bloc de code
}
exceptionHandling.email=bugs@domain.edu
{code}
{note}

Ce mécanisme est rendu possible par la définition 
Remarque

Ce mécanisme est rendu possible par la définition d'un

bean

utilisant

la

classe

_

PropertyPlaceholderConfigurer

_

de

Spring

dans

le

fichier

*

properties/applicationContext.xml

* {code}

Bloc de code

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <value>classpath:/properties/defaults.properties</value>
      <value>classpath:/properties/config.properties</value>
      <value>file:${application.config.location}</value>
    </list>
  </property>
  <property name="ignoreResourceNotFound" value="true" />
</bean>

Ici on définit les propriétés dans le fichier defaults.properties.Elles sont éventuellement écrasées par celles définies dans config.properties.

Ici on utilise aussi la possibilité de surcharger ces valeurs par une référence à un fichier qui sera précisé par une option au lancement de la JVM (Ex : -Dapplication.config.location=/tmp/foo.properties). Afin que le propertyConfigurer ne lève pas une exception au cas où cette dernière possibilité n'est pas utilisée on positionne une des ces propriétés (ignoreResourceNotFound) pour qu'il ignore les éventuelles ressources absentes.

L'héritage de configuration

Spring n'oblige pas à saisir, dans toutes les définitions de beans, les mêmes propriétés. Pour cela, il est possible d'utiliser le mot-clé parent.

Le « parent » a un attribut abstract="true" car il ne doit pas être créé en mémoire par Spring. Cette notation permet de se rapprocher de l'héritage Java qui est beaucoup utilisé dans esup-commons.

Exemple d'un bean « parent » ayant aussi lui-même un « parent » :

Bloc de code
</bean>
{code}


{note}

h2. L'héritage de configuration

_Spring_ n'oblige pas à saisir, dans toutes les définitions de _beans_, les mêmes propriétés. Pour cela, il est possible d'utiliser le mot-clé *parent*.

Le «&nbsp;parent&nbsp;» a un attribut *abstract="true"* car il ne doit pas être créé en mémoire par _Spring_. Cette notation permet de se rapprocher de l'héritage _Java_ qui est beaucoup utilisé dans _esup-commons_.

Exemple d'un _bean_ «&nbsp;parent&nbsp;» ayant aussi lui-même un «&nbsp;parent&nbsp;» :

{code}
<bean
  id="abstractApplicationAwareBean"
  parent="abstractI18nAwareBean"
  abstract="true">
    <property name="applicationService" ref="applicationService" />
</bean>
{code}

{note}
Remarque

L'attribut

*

scope

*

(voir

ci-après)

n'est

pas

héritable,

il

est

donc

inutile

de

le

préciser

pour

un

_

bean

_

abstrait.

{note} h2. Vérification des _beans_ Les _beans_ manipulés par _Spring_

Vérification des beans

Les beans manipulés par Spring n'ont

...

pas,

...

par

...

défaut,

...

de

...

dépendances

...

particulières

...

avec

...

Spring

...

.

...

Il

...

est,

...

par

...

contre,

...

possible

...

de

...

sciemment

...

introduire

...

une

...

dépendance

...

avec

...

Spring

...

pour

...

obtenir

...

des

...

services

...

supplémentaires.

...

Faire

...

en

...

sorte

...

que

...

votre

...

bean

...

implémente

...

l'interface

...

InitializingBean

...

de

...

Spring

...

en

...

fait

...

partie.

...

Cette

...

interface

...

vous

...

oblige

...

à

...

implémenter

...

une

...

méthode

...

afterPropertiesSet

...

qui

...

sera

...

appelée

...

par

...

Spring

...

juste

...

après

...

l'initialisation

...

du

...

bean

...

.

...

Cette

...

méthode

...

vous

...

permet

...

de

...

vérifier

...

que

...

toutes

...

les

...

propriétés

...

sont

...

bien

...

initialisées.

...

Si

...

ce

...

n'est

...

pas

...

le

...

cas,

...

vous

...

pouvez,

...

par

...

exemple,

...

lever

...

une

...

exception

...

ou

...

affecter

...

une

...

valeur

...

par

...

défaut.

...

On

...

trouvera

...

par

...

exemple

...

:

{
Bloc de code
}
public void afterPropertiesSet() {
  super.afterPropertiesSet();
  if (!StringUtils.hasText(exceptionView)) {
    exceptionView = DEFAULT\__SERVLET_\_EXCEPTION_VIEW;
    logger.info(getClass() + ": no exceptionView set, using default \[" + exceptionView + "\]");
  }
}
{code}

h2. Portée des beans

_Spring_ offre une notion de portée (*scope*).

Par défaut, un _bean_ est de portée *singleton*. _Spring_ crée une seule instance de ce _bean_ pour toute la durée d'exécution de l'application.

Il existe aussi des portées *session* et *request* qui, respectivement, permettent d'avoir une instance du _bean_ par session utilisateur (au sens d'une application web) ou par requête (au sens HTTP). Cette notion est particulièrement intéressante pour les contrôleurs web d'une application. Ces derniers sont en général des _beans_ de portée *session*, comme par exemple :
{code}

Portée des beans

Spring offre une notion de portée (scope).

Par défaut, un bean est de portée singleton. Spring crée une seule instance de ce bean pour toute la durée d'exécution de l'application.

Il existe aussi des portées session et request qui, respectivement, permettent d'avoir une instance du bean par session utilisateur (au sens d'une application web) ou par requête (au sens HTTP). Cette notion est particulièrement intéressante pour les contrôleurs web d'une application. Ces derniers sont en général des beans de portée session, comme par exemple :

Bloc de code
<bean id="administratorsController"
  class="[...].formation.web.controllers.AdministratorsController"
  parent="abstractContextAwareController"
  scope="session" />
{code}

Usuellement,

...

un

...

bean

...

de

...

scope

...

request

...

peut

...

faire

...

référence,

...

via

...

ses

...

propriétés,

...

à

...

un

...

bean

...

de

...

scope

...

session

...

ou

...

singleton

...

.

...

De

...

même,

...

un

...

bean

...

de

...

scope

...

session

...

peut

...

faire

...

référence

...

à

...

un

...

bean

...

de

...

scope

...

singleton

...

.

...

Une

...

bonne

...

architecture

...

nous

...

amène

...

d'ailleurs

...

à

...

utiliser

...

dans

...

ce

...

sens

...

l'injection

...

de

...

beans.

...

Par

...

défaut,

...

la

...

réciproque

...

provoque

...

une

...

exception

...

...

...

mais

...

il

...

est

...

cependant

...

possible

...

de

...

réaliser

...

cette

...

réciproque

...

par

...

le

...

biais

...

de

...

l'

...

aop

...

,

...

et

...

cela

...

très

...

simplement.

...

Concrètement

...

si

...

nous

...

voulons

...

ici

...

injecter

...

le

...

bean

...

administratorsController

...

qui

...

est

...

de

...

scope

...

session

...

dans

...

un

...

bean

...

de

...

scope

...

singleton,

...

on

...

utilisera

...

la

...

balise

...

aop:scoped-proxy

...

comme

...

ceci

...

dans

...

la

...

déclaration

...

du

...

bean

...

administratorsController :

Bloc de code
* :
\\
{code}
<bean id="administratorsController"
  class="[...].formation.web.controllers.AdministratorsController"
  parent="abstractContextAwareController"
  scope="session">
 <aop:scoped-proxy/>
</bean>
{code}

Pour

...

ce

...

faire,

...

on

...

aura

...

pris

...

soin

...

de

...

déclarer

...

comme

...

il

...

se

...

doit

...

l'espace

...

de

...

noms

...

aop,

...

avec

...

dans

...

la

...

balise

...

racine

...

du

...

fichier

...

de

...

configuration

...

de

...

beans

...

Spring

...

ceci

...

:

{
Bloc de code
}
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="
	http://www.springframework.org/schema/aop"        
       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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" >
{code}
{HTMLcomment}
h2. Récupération des _beans_

Il est possible de récupérer un _bean_ à partir de son nom à partir du code JAVA. La classe *BeanUtils* fournie par _esup-commons_ V1 n'est plus utilisée.

On utilise un mécanisme interne à Spring basé sur l'implémentation de *...
</beans>

HTML Comment

Récupération des beans

Il est possible de récupérer un bean à partir de son nom à partir du code JAVA. La classe BeanUtils fournie par esup-commons V1 n'est plus utilisée.

On utilise un mécanisme interne à Spring basé sur l'implémentation de org.springframework.context.ApplicationContextAware

...

esup-commons

...

V2

...

fournit

...

une

...

telle

...

implémentation

...

qu'il

...

suffit

...

de

...

déclarer

...

dans

...

un

...

fichier

...

de

...

configuration

...

Spring

...

(ex

...

:

...

properties/applicationContext.xml

...

)

...

:

...

Bloc de code

...


<bean id="app_context" class="org.esupportail.commons.context.ApplicationContextHolder"/>

...

Depuis

...

le

...

code

...

java,

...

on

...

utilisera

...

:

...

Bloc de code

...


ApplicationContext springContext = ApplicationContextHolder.getContext();
DomainService domainService = (DomainService) springContext.getBean("domainService");

...

Avertissement
  • L'utilisation

...

  • de

...

  • cette

...

  • méthode

...

  • devrait

...

  • rester

...

  • exceptionnelle

...

  • (mode

...

  • batch

...

  • par

...

  • exemple)

...