L'IoC container è la parte di Spring che si occupa di instanziare e configurare gli oggetti che vengono inseriti in esso, che prendono il nome di beans.
I beans vengono configurati attraverso dei metadati che possono essere dei file xml o delle Java annotations. Di default i metadati vengono letti solo dagli xml, per abilitare l'uso delle annotations c'è bisogno di configurare l'ApplicationContext.
Come anticipato in precedenza la parte di IoC e di DI viene implementata attraverso la BeanFactory e l'ApplicationContext. Dato che l'ApplicationContext è un superset della BeanFactory, se ne consiglia l'uso, e da qui in avanti faremo riferimento solo all'ApplicationContext. Ci sono vari tipi di ApplicationContext forniti da Spring, a seconda dell'applicazione che si deve sviluppare. Per esempio per applicazioni stand alone ci sono il ClassPathXmlApplicationContext e il FileSystemXmlApplicationContext, mentre per le applicazioni enterprise c'è il WebApplicationContext, che viene instanziato attraverso un serlvet listener. Tutti gli ApplicationContext hanno bisogno dei metadati di configurazione e quindi per instanziarne uno abbiamo bisogno prima di scrivere un file xml. Facciamo un esempio: usando sempre come riferimento la gestione di una videoteca vediamo come inizializzare l'IoC e la classe VideoManager. Innanzitutto creaiamo i metadati attraverso un file che chiameremo applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans" ............>
<!-- import di altri metadati -->
<import resource="otherbeans.xml"/>
<!-- DEFINIZIONE DEL SERVIZIO -->
<bean id="dvdService" class="it.mrwebmaster.DvdServiceImpl" scope="singleton" />
<!-- DEFINIZIONE DEL VIDEO MANAGER-->
<bean id="videoManager" class="it.mrwebmaster.VideoManager" scope="prototype">
<property name="dvdService" ref="dvdService" />
</bean>
</beans>
Nell'esempio si vede che è possibile integrare più file di metadati in modo da dividere le difinizioni dei beans. Per ora non è importante capire la sintassi dei metadati (che verrà illustrata più avanti), ma le potenzialità di Spring. Eliminiano dal costruttore dalla classe VideoManager l'inizializzazione del dvdService e creiamo il getter e il setter per il dvdService:
public VideoManager() {
super();
}
public List<Dvd> getAvalaibleDvdList(){
//......
return availabeDvdList;
}
public void setDvdService(DvdService dvdService) {
this.dvdService = dvdService;
}
public DvdService getDvdService() {
return dvdService;
}
Vediamo ora come inizializzare l'IoC:
/**
* Instanzio l'IoC container
*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
/**
* Recupero la classe VideoManager
*/
VideoManager videoManager = (VideoManager) applicationContext.getBean("videoManager");
/**
* Stampo la lista dei dvd disponibili
*/
List<Dvd> avalaibleDvdList = videoManager.getAvalaibleDvdList();
for (Dvd dvd : avalaibleDvdList) {
System.out.println(dvd.getTitolo());
}
Come abbiamo visto, scrivendo poche righe di xml e di codice siamo riusciti a configurare completamente la nostra applicazione.
I vantaggi nell'usare Spring che sono stati descritti nei capitoli precedenti saltano subito all'occhio:
- I beans della nostra applicazione, VideoManger e DvdServiceImpl non implementano nessusa interfaccia o classe astratta, e le dipendenze dall'IoC container sono nulle.
- Se si decide di cambiare l'implementazione dell'DvdService, o di aggiungerne delle altre, basta cambiare il file applicationContext.xml,senza toccare il codice della VideoManager, questo grazie all'uso delle interfacce.
- Sempre grazie all'uso interfacce è facile creare dei test per la nostra applicazione.
Sempre facendo riferimento al nostro esempio avremmo potuto usare il FileSystemXmlApplicationContext in questo modo:
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("/path/applicationContext.xml");
Invece per usare il WebApplicationContext in un'applicazione enterprise, nel nostro web.xml bisogna aggiungere (l'esempio completo di un'applicazione enterprise che fa uso di Spring verrà illutrato nell'ultimo capitolo di questa guida):
<!-- SPRING -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>