Spring, Eclipse, Maven e la più semplice applicazione realizzabile. (Parte 2)
6 08 2008Dopo aver configurato l’applicazione e risolto tutte le dipendenze, si possono iniziare a creare i primi oggetti gestiti da Spring.
La filosofia che sta alla base di Spring è che tutti gli oggetti con i quali si lavora dovrebbero essere “semplici” e privi di dipendenze vincolanti verso altri oggetti. In pratica, secondo le linee guida, se utilizzando Spring un qualunque oggetto inizia a dipendere da altre librerie bisognerebbe fermarsi e chiedersene il motivo.
In Spring, il mattone fondamentale per lo sviluppo è il Pojo, ovvero la classe Java pura e semplice (per una definizione di Pojo). Ultimamente si è preferito anche sostituire a Spring Bean, il termine di Oggetto Gestito da Spring, per sgomberare ulteriormente il campo dalla possibilità di fraintendere il termine Bean (e assimilarlo ad esempio ad oggetti come gli EJB) per ribadire invece che si parla di semplici classi Java.
Togliendo agli oggetti la responsabilità di istanziare e richiamare gli altri oggetti di cui hanno bisogno, diventa necessario che questa operazione venga svolta da qualcos’altro, in questo caso dal framework.
Tramite un processo di configurazione il framework viene istruito su cosa rendere disponibili a chi.
L’esempio più semplice che possiamo fare è di creare un singolo oggetto, configurarlo e richiamarlo per poterlo utilizzare.
L’oggetto che creiamo è l’interfaccia “Hello” con la relativa classe “HelloImpl.java” che la implementa, configurata come un bean con una singola proprietà:
package com.bernesco;
public class HelloImpl implements Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = processor.process(name);
}
}
Per istruire Spring compiliamo un file xml (Spring supporta altri metodi di configurazione, basta cercare sulla documentazione), che chiamiamo “applicationContext.xml”:
www.springframework.org/schema/beans " title="http://www.springframework.org/schema/beans/spring-beans.xsd\">" class="autohyperlink" target="_blank">www.springframework.org/schema/beans/spring-beans.xsd">
In questo file ci basta indicare la classe dell’oggetto e un “id” che useremo per recuperarlo.
Per terminare, dobbiamo creare “qualcosa” che faccia il boot del framework, nel nostro caso una classe con un metodo “main”:
package com.bernesco;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Starter {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
Hello myHello = (HelloImpl) applicationContext.getBean("hello");
myHello.setName("Alessio");
System.out.println(myHello.getName());
}
}
Avviando questa classe, nella console si vedrà il boot di Spring, con il caricamento dell’oggetto “hello”.
Aug 6, 2008 6:08:43 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@cac6db: display name [org.springframework.context.support.ClassPathXmlApplicationContext@cac6db]; startup date [Wed Aug 06 18:08:43 CEST 2008]; root of context hierarchy Aug 6, 2008 6:08:43 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [applicationContext.xml] Aug 6, 2008 6:08:43 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@cac6db]: org.springframework.beans.factory.support.DefaultListableBeanFactory@f0625 Aug 6, 2008 6:08:43 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@f0625: defining beans [capitalizer,hello]; root of factory hierarchy
Con un singolo oggetto il giro funziona ma non è molto chiaro dove entra in gioco Spring.
Supponiamo di avere ora due classi, Hello ed una classe Processor, che in qualche maniera “elabora” i dati contenuti in Hello.
Per fare in modo che Hello possa usare questa classe senza Spring dovremmo istanziare l’oggetto dall’interno di Hello, oppure istanziarlo esternamente e passarglielo dal costruttore o tramite un setter.
In ogni caso inizieremmo a costruire una rete di dipendenze che renderebbe l’oggetto difficile da testare.
Con Spring invece ci basta aggiungere all’xml la definizione della nuova classe Processor e aggiungere che in fase di richiesta, dovrà essere resa disponibile alla classe Hello un istanza di Processor.
Questa “disponibilità” avverrà tramite il passaggio dell’istanza di processor ad un setter di Hello.
Iniziamo con l’oggetto Processor e con la sua implementazione, la classe CapitalizerImpl, che semplicemente rende in maiuscolo la stringa che le viene passata:
package com.bernesco;
public interface Processor {
public String process(String value);
}
package com.bernesco;
public class CapitalizerImpl implements Processor {
public String process(String value) {
return value.toUpperCase();
}
}
l’xml, che diventa così:
" title="http://www.springframework.org/schema/beans/spring-beans.xsd\">" class="autohyperlink" target="_blank">www.springframework.org/schema/beans/spring-beans.xsd">
In pratica, ora vengono definiti due oggetti, HelloImpl e CapitalizerImpl. In più, HelloImpl ora “riceverà” un istanza di CapitalizerImpl.
Per rendere tutto funzionante, l’ultima modifica la facciamo all’oggetto HelloImpl, che ora contiene un setter per ricevere l’istanza di Processor:
package com.bernesco;
public class HelloImpl implements Hello {
private String name;
private Processor processor;
public String getName() {
return name;
}
public void setName(String name) {
this.name = processor.process(name);
}
public void setProcessor(Processor processor) {
this.processor = processor;
}
}
In pratica il risultato ottenuto ora è che, quando viene richiesta un istanza di Hello a Spring, Spring si occupa anche di istanziare e passare a Hello tutti gli oggetti necessari per il suo funzionamento, senza che sia Hello a doversene occupare.
Il prossimo passaggio sarà vedere come in fase di test questo permetta ad esempio di passare ad una classe delle istanze di oggetti differenti da quelli che utilizza a runtime, facilitando di molto tutte le procedure di test (ad esempio oggetti data precompilati o che accedono ad un database differente da quello di produzione).







