Définir la portée d’un bean
Spring propose plusieurs stratégies d’instancaition. Les plus courantes sont :
- singleton : une seule instance partagée (comportement par défaut)
- prtootype : une nouvelle instance à chaque demande
<bean id="compteService" class="demo.service.CompteService" scope="prototype">
<property name="compteRepo" ref="compteRepo"/>
</bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
CompteService c1 = ctx.getBean("compteService", CompteService.class);
CompteService c2 = ctx.getBean("compteService", CompteService.class);
System.out.println(c1 == c2); // false
Injection de collections
Supposons un repository capable de recevoir des paramètres de configuration sous forme de collections :
package demo.repo;
import java.util.*;
public class CompteRepo {
private Set<String> blacklist;
private List<Integer> priorites;
private Map<String, String> mapping;
// setters & getters omis
@Override
public String toString() {
return blacklist.size() + "|" + priorites.size() + "|" + mapping.size();
}
}
Configuration XML :
<bean id="compteRepo" class="demo.repo.CompteRepo">
<property name="blacklist">
<set>
<value>spam@example.com</value>
</set>
</property>
<property name="priorites">
<list>
<value>1</value>
<value>2</value>
</list>
</property>
<property name="mapping">
<map>
<entry key="EUR" value="€"/>
<entry key="USD" value="$"/>
<entry key="JPY" value="¥"/>
</map>
</property>
</bean>
CompteRepo repo = ctx.getBean("compteRepo", CompteRepo.class);
System.out.println(repo); // 1|2|3
Autowiring automatique
L’attribut autowire accepte plusieurs modes :
byName: correspondance par nom de propriétébyType: correspondance par typeconstructor: injection via le constructeurno: désactivation
package demo.repo;
public class CompteRepo {
private int version;
// setters & getters
public String toString() { return "v" + version; }
}
<bean id="compteRepo" class="demo.repo.CompteRepo">
<property name="version" value="1"/>
</bean>
<bean id="compteRepoBeta" class="demo.repo.CompteRepo">
<property name="version" value="2"/>
</bean>
<bean id="compteService" class="demo.service.CompteService"
autowire="byName"/>
Spring injectera le bean nommé compteRepo dans la propriété compteRepo de CompteService.
Pour éviter la répétition, on peut déclarer default-autowire="byName" sur l’élément racine <beans>.
Gestion du cycle de vie
Initialisation différée
Ajouter lazy-init="true" retarde la création du bean jusqu’à sa première utilisation.
<bean id="lourdService" class="demo.service.LourdService" lazy-init="true"/>
On peut aussi activer le comportement par défaut :
<beans default-lazy-init="true"> ... </beans>
Callbacks personnalisés
Les attributs init-method et destroy-method désignent les méthodes à invoquer après la création et avant la destruction.
package demo.service;
public class CompteService {
public void demarrer() {
System.out.println("Service démarré");
}
public void arreter() {
System.out.println("Service arrêté");
}
}
<bean id="compteService" class="demo.service.CompteService"
init-method="demarrer" destroy-method="arreter">
<property name="compteRepo" ref="compteRepo"/>
</bean>
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("beans.xml");
CompteService service = ctx.getBean(CompteService.class);
ctx.close(); // déclenche la méthode arreter()
Note : pour les beans de portée prototype, Spring ne gère pas la destruction ; la responsabilité revient au code client.