JUG Sardegna supports Devoxx 2012
Vuoi ricevere uno zainetto? Clicca qui

Java User Groups
Java.net Partner
Get Firefox!

Spring2 Core

Articolo di MassimilianoDessi
Spring 2.0 Core
vers 0.1



In questo articolo e i successivi, faremo conoscenza con Spring, un framework “leggero”
che sta avendo una grande diffusione nel mondo Java, sia in ambito Open source , sia
a livello industriale.
Spring è un lightweight container, completamente basato sulla Iniezione delle dipendenze, chiamata più comunemente Inversione del Controllo (IoC), incontra sempre più i favori degli sviluppatori e degli architetti software, grazie alla elevata qualità, semplicità e Design Object Oriented “puro”, che il team internazionale di sviluppo formato da professionisti con esperienze pluriennali, pone come propri obiettivi.
Spring è leggero perché non forza in nessun modo le scelte architetturali, può essere usato per costruire interamente qualsiasi tipo di applicazione, oppure può essere usato solo in parte, è un container perché gestisce il ciclo di vita e la configurazione degli oggetti.
Fornisce “out of the box” funzionalità J2EE.

IoC

Per spiegare cosa si intende per Inversione del controllo, si pensi al normale flusso di esecuzione di una applicazione. Passo dopo passo durante lÂ’ esecuzione, gli oggetti ne richiameranno altri , e questi a loro volta altri ancora.
Questa visione “a runtime”, vista ad un livello di astrazione più alto e con una prospettiva architetturale,
porta a individuare tra gli oggetti, delle relazioni di dipendenza.
LÂ’azione del “recuperare”, gli altri oggetti, va dalla semplice istanziazione di nuovi oggetti, al lookup jndi per recuperare risorse locali o remote, cioè la classe attraverso cui passa il flusso di esecuzione deve anche procurarsi le risorse per eseguire il proprio lavoro.
LÂ’ iniezione delle dipendenze operata da Spring, viene in aiuto proprio in questo frangente, iniettando in vari modi, scelti dal programmatore, gli oggetti di cui ha bisogno ciascun oggetto.
Il nome Ioc al pattern è stato dato da Martin Fowler [6] e viene indicato con la frase “Hollywoodiana”, “non chiamarmi, ti chiamo io”.


Tipi di Ioc

I tipi più comuni e più usati sono essenzialmente tre:

1. Implementazione di una interfaccia dedicata .
2. Setter based, le dipendenze vengono soddisfatte tramite i metodi setter
3. Constructor based, le dipendenze vengono soddisfatte passando dai costruttori

Spring usa il tipo due e il tipo tre, di solito si è portati ad usare quasi sempre i setter , riservando lÂ’iniezione con i costruttori ad oggetti “legacy” che non si vogliono modificare e a cui viene assegnato uno stato iniziale attraverso il costruttore.
Un grande pregio di Spring è che non forza assolutamente il programmatore in nessuna scelta, perciò quanto detto può essere completamente ribaltato.


Benefici dellÂ’ IoC

La scrittura di classi con dei metodi set per permettere a Spring di iniettare le dipendenze, porta con se delle conseguenze implicite:
1. Le classi diventano dei POJO (Plain Old Java Object), cioè dei semplici bean, e si è portati a una maggiore separazione delle competenze e responsabilità di ogni singolo oggetto, rendendo le classi più semplici
2 Viene incoraggiata la programmazione per interfacce
3 Gli oggetti diventano fortemente disaccoppiati tra loro
4 La testabilità di ogni oggetto è facilitata
5 Se le responsabilità e le competenze di ogni singolo oggetto sono ben distinte, è di più facile applicazione la programmazione ad aspetti (AOP)

Naturalmente, benchè queste siano benefici impliciti, una applicazione scritta male non diventa perfetta applicando lÂ’IoC, quindi come sempre, tutto dipende dalla applicazione pratica che viene fatta.


Architettura Spring

Vediamo ora da quali componenti è formato Spring



Il package Core contiene le parti fondamentali per realizzare l' IoC.
L' IoC viene realizzato per mezzo della interfaccia BeanFactory che usando il pattern factory rimuove la necessità di singleton e permette di disaccopiare la configurazione e le dipendenze.

Il package Context fornisce l' accesso ai bean, fornisce il supporto per i resources-bundle, la propagazione degli eventi, il caricamento delle risorse e la creazione trasparente dei contesti.

Il package DAO (data acces object) fornisce uno strato di astrazione per JDBC.
Fornisce una modalità dichiarativa per la gestione delle transazioni (transaction management) non solo per alcune classi, ma per tutti i POJO che ne abbiano necessità.

Il package ORM fornisce l' integrazione con i più diffusi object-relational mapping (JDO, Hibernate e iBatis,Oracle TopLink, Apache OJB), sfruttando le caratteristiche di transazionalità definite precedentemente.

Il package AOP fornisce una implementazione aderente alle specifiche AOP Alliance dell' Aspect programming.

Il package WEB fornisce l 'integrazione con le caratteristiche orientate al web, come inizializzazione di contesti usando servlet listener, e la creazione di contesti applicativi per applicazioni web.
Questo è il package da usare nel caso si voglia integrare Struts o WebWork

Il package WEB MVC fornisce una implementazione Model View Controller per applicazioni web, fornendo inoltre tutte le altre caratteristiche di Spring


Diversi Scenari di applicazione
Spring usato in una Web Application in tutti i livelli



Come middle tier di un framework web



In una applicazione in cui si accede tramite web-services:



Con EJB



Altri utilizzi si possono avere in applicazioni standalone (Swing o SWT) usando la parte del progetto denominata Spring Rich Client.


Funzionamento

Il funzionamento di Spring come container IoC ruota attorno alla interfaccia BeanFactory.
Grazie a questa interfaccia, è possibile configurare e gestire qualsiasi oggetto, risolvere le dipendenze tra i vari oggetti, configurarne il ciclo di vita nel caso si avesse bisogno di chiamate a particolari metodi di costruzione e di distruzione.
Una volta passati i file di configurazione (più comunemente in formato xml) ad una implementazione di una BeanFactory, verranno creati i bean contenuti nella configurazione e risolte le dipendenze tra essi.
Nei file di configurazione sono dichiarati tanti bean quanti sono gli oggetti che vogliamo gestisca Spring con lÂ’IoC.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- V I E W  R E S O L V E R -->

  <bean name="jugavis.viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:viewClass="org.springframework.web.servlet.view.JstlView"
    p:prefix="./WEB-INF/jsp/"
    p:suffix=".jsp"/>

  <bean name="jugavis.reportViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"
    p:order="1"
    p:basename="views"/>

...
</beans>



Le varie sottointerfacce di BeanFactory, introducono funzionalità ulteriori rispetto ad essa che
offre le funzionalità base offerte di accesso a qualsiasi bean, un bean può essere chiamato direttamente , per nome con il metodo getBean(String name, Class requiredType), o con altri metodi di reperimento in base ad altri parametri.
Nella stragrande maggioranza dei casi, si usano le implementazioni della sottointerfaccia ApplicationContext.
Se le altre implementazioni della BeanFactory offrono funzionalità a basso livello, lÂ’ ApplicationContext offre funzionalità per usare Spring come framework.
Funzionalità come le notifiche interne agli oggetti del container per determinati eventi, il supporto per i messaggi localizzati (MessageSource), il caricamento diretto dei file (ResourceLoader),
il caricamento dei file di configurazione in un contesto Web, il caricamento dei file da ClassPath , più altre funzionalità, specifiche a seconda del tipo di implementazione dellÂ’ ApplicationContext.
LÂ’ unico caso in cui viene suggerito lÂ’ uso di una implementazione della BeanFactory anziché della ApplicationContext è nel caso si richieda un applicazione che disporrà di pochissima memoria come nel caso di una midlet.
Come sottoclasse di BeanFactory, anche lÂ’ApplicationContext, eredita i comportamenti di una gerarchia di interfacce, le più significative sono:

-ApplicationEventPublisher, permette la notifica di eventi ai bean che sono registrati anche come listener.
-HierarchicalBeanFactory, una bean factory può essere parte di una gerarchia di bean factory, grazie a questa interfaccia si può costruire una applicazione dividendo i file di configurazione per layer, lÂ’intera gerarchia viene vista come una unica BeanFactory.
-ListableBeanFactory, permette lÂ’elencazione di tutti i bean della BeanFactory in base a nome o tipo.
-AutowireCapableBeanFactory, viene usata nellÂ’ integrazione con altri framework di cui Spring non deve gestire il ciclo di vita (Es. WebWork Actions e Tapestry Page objects)


Il ciclo di vita di un bean

Vediamo ora quali sono gli eventi che un bean “vive” all’interno di Spring, e che possiamo usare per personalizzare il comportamento dei nostri oggetti.
Vediamo un bean caricato dentro un Container BeanFactory (usando un Container ApplicationContext avremo un evento in più ).
Nota: Indichiamo la BeanFactory e lÂ’ ApplicationContext come Container perché vedremo gli eventi sul bean rispetto al suo contenitore.

1. Il container legge la definizione del bean e istanzia il bean.
2. Usando lÂ’iniezione delle dipendenze, vengono valorizzate le dipendenze specificate nella definizione del bean.
3. Se il bean implementa lÂ’ interfaccia BeanNameAware, viene chiamato il metodo setBeanName() e viene passato lÂ’ id specificato nella definizione del bean.
4. Se il bean implementa lÂ’interfaccia BeanFactoryAware, viene chiemato il metodo
setBeanFactory() e viene passato il riferimento al container (BeanFactory)
5. Se il bean implementa lÂ’ interfaccia BeanPostProcessor viene chiamato il metodo postProcessBeforeInitialization per eventuali operazioni prima della inizializzazione
6. Se è presente un init-method (dichiarato anche nella definizione del bean) , viene chiamato
7. Se il bean implementa lÂ’ interfaccia BeanPostProcessor viene chiamato il metodo postProcessAfterInitialization per eventuali operazioni dopo lÂ’ inizializzazione


Ora il bean è pronto allÂ’ uso !
Quando il bean deve essere distrutto alla chiusura della applicazione ad esempio, se implementa lÂ’interfaccia DisposableBean, viene chiamato il metodo destroy.
Se invece nella definizione del bean è dichiarato un destroy-method, viene chiamato questo.

Se invece di una BeanFactory, il container del bean è un ApplicationContext
dopo il punto 4 e prima del 5 se il bean implementa lÂ’interfaccia ApplicationContextAware ,
viene chiamato il metodo setApplicationContext che passa al bean il riferimento allÂ’ ApplicationContext.


Uso pratico

Vediamo come iniziare ad usare le varie implementazioni dellÂ’ ApplicationContext

Nel caso di una applicazione stand alone, con file di configurazione xml presenti nel classPath:


ApplicationContext appContext = new ClassPathXmlApplicationContext("/com/framesrl/business/conf/applicationContext.xml");


Oppure più brevemente


ApplicationContext appContext = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");


Nel caso si abbiano più file passiamo un String[] paths al costruttore dellÂ’ ApplicationContext.

Se i file di configurazione sono situati in un punto preciso del FileSystem:


ApplicationContext appContext = new FileSystemXmlApplicationContext("/percorso/al/miofile/di/configurazione/applicationContext.xml");


Una buona pratica consiste nel dividere i file di configurazione per layer della applicazione:


String[] paths ={"/percorso/al/miofile/di/configurazione/applicationContext-servicelayer.xml",/percorso/al/miofile/di/configurazione/applicationContext-daolayer.xml"};
ApplicationContext appContext = new FileSystemXmlApplicationContext(paths);


Quindi a seconda delle situazioni avremo:

ClassPathResources res = new ClassPathResources("/percorso/alMioFile/ configurazione/applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);


oppure :

InputStream inputStr = new FileInputStream("/percorso/al/miofile/di/configurazione/applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(inputStr);


o anche:

ClassPathResources res = new ClassPathResources ("/percorso/al/miofile/di/configurazione/applicationContext.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader(factory);
Reader.loadBeanDefinitions(res);



Spring Core II parte


Autore
Massimiliano Dessì (http://www.jugsardegna.org/vqwiki/jsp/Wiki?MassimilianoDessi) ha iniziato a lavorare alla Sistemi Informativi (società IBM) , attualmente e' consulente per il Centro Servizi della regione Sardegna , dove sviluppa applicazioni J2EE basate su Spring, utilizzando metodologie agili.
Cura la versione italiana di Jetspeed e di Spring BeanDoc, sviluppa la versione Web del progetto Jug Avis utilizzando Spring, tiene seminari e corsi su tecnologie J2EE e collabora con società ed enti italiani ed esteri per la realizzazione di portali J2EE.
EÂ’ co-fondatore e consigliere del Jug Sardegna (http://www.jugsardegna.org).
EÂ’ coordinatore dello Spring Framework Italian User Group (http://it.groups.yahoo.com/group/SpringFramework-it )
e del Jetspeed Italian Group http://it.groups.yahoo.com/group/jetspeed-it e del Groovy Italian User Group http://it.groups.yahoo.com/group/GroovyItalianUserGroup

Bibliografia
[1] Rod Johnson, Juergen Hoeller, Alef Arendsen, Thomas Risberg, Colin Sampaleanu, " Java Development with the Spring Framework", Wrox, 2005, ISBN: 0-7645-7483-3, http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764574833.html
[2] Craig Walls and Ryan Breidenbach, " Spring in Action", Manning, 2005, ISBN 1932394354, http://www.manning.com/books/walls2
[3] Rob Harrop, Jan Machacek, "Pro Spring", Apress, 2005, ISBN 1-59059-461-4, http://www.apress.com/book/bookDisplay.html?bID=405
[4] Rod Johnson, Juergen Hoeller, " J2EE Development without EJB", Wrox, 2004, ISBN 0-7645-5831-5, http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764558315.html
[5] Rod Johnson, " J2EEDesign and Development ", Wrox, 2002, ISBN 0-7645-4385-7, http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764543857.html
[6] Seth Ladd, Darren Davison, Steven Devijver, Colin Yates " Expert Spring MVC and Web Flow", Apress, 2006, ISBN 159059584X, http://apress.com/book/bookDisplay.html?bID=10048


Riferimenti
[7]”Inversion of Control Containers and the Dependency Injection pattern”: http://www.martinfowler.com/articles/injection.html
[8]”Sito Spring”: http://www.springframework.org/
[9] ”Forum Spring”: http://forum.springframework.org/
[10]”Raccolta articoli e recensioni in italiano su Spring”: http://www.jugsardegna.org/vqwiki/jsp/Wiki?SpringFramework
[11]” Spring Framework Italian User Group”: http://it.groups.yahoo.com/group/SpringFramework-it


VeryQuickWiki Version 2.7.8 | Admin
Copyright © 2003-20011 Java User Group Sardegna Onlus. - Java, the Java Coffee Cup Logo and the Duke Logo are trademarks or registered trademarks of Oracle corporation in the U.S. and other countries.