Spring JavaConfig (parte 1)

Introduzione

Non molto tempo fa i parametri di configurazione di un software (java) erano rigidamente codificati (hard-coded) al suo interno, successivamente furono esternalizzati in file di properties (semplici file di testo), in modo da non dover ricompilare il codice a seguito di modifiche nella configurazione, ed infine, molto grazie a Spring, da semplici file di testo si è passato all’utilizzo di file XML. L’introduzione dell’annotazione @Configuration in Spring 3 per la configurazione del container IoC sembra quindi un passo indietro all’approccio iniziale.

Il component scanning e l’autowiring con annotation hanno reso Spring molto simile al modo in cui la specifica J2EE gestisce la Dependency Injection, quindi l’esternalizzazione con l’uso dell’XML rimaneva forse la sola caratteristica distintiva, anche perché consentiva di mantenere la configurazione in pochi file piuttosto che diffonderla all’interno del codice. L’utilizzo dell’XML comporta però diversi svantaggi che spesso vengono sottovalutati:

  1. Non è type-safe, quindi un qualsiasi errore nel file (anche di semplice battitura) è rilevato esclusivamente allo startup dell’ApplicationContext di Spring. Questo comporta inutili ricicli che rallentano lo sviluppo, soprattutto quando si tratta di applicazioni web che devono essere rideployate.
  2. L’XML è verboso al punto da divenire molto grandi in applicazioni mediamente complesse, per cui si è costretti a suddividere la configurazione in più file.
  3. Non è possibile navigare nei vari file di configurazione e se si desidera trovare dove un determinato bean viene definito è necessario eseguire una ricerca full-text.

Entrambi gli approcci quindi hanno vantaggi e svantaggi, però riportare la configurazione nel codice ha diverse implicazioni interessanti:

  1. Tutti gli IDE supportano il type-checking, il code completion, il refactoring e la ricerca delle referenze nel codice.
  2. Per uno sviluppatore java è molto più semplice codificare concetti come: creazione di bean, inizializzazione, etc. in java piuttosto che con inventare metodi complicati in XML.
  3. l’uso di design pattern specifici possono rendere il codice (di configurazione) chiaro e leggibile.

JavaConfig si candida quindi come una valida alternativa sia all’uso dell’XML che all’autowiring. Esso infatti unisce il vantaggio del disaccoppiamento dell’XML con il compile-time check di Java. In un certo senso JavaConfig può essere visto come l’equivalente di un file XML ma codificato in linguaggio Java.

Configurazione

L’annotazione principale di Spring JavaConfig è @Configuration. Questa indica al container che la classe contiene elementi di configurazione, che sostanzialmente si concretizzano in metodi annotati con @Bean, i quali definiscono la logica di creazione, configurazione e inizializzazione degli oggetti che verranno gestiti dal contenitore Spring IoC. Vediamo un primo semplice esempio di configurazione:

Quanto JavaConfig si “imbatte” in questa classe, annotata con @Configuration, ricerca tutti i metodi annotati con @Bean, li esegue e registra i valori restituiti nel container. Di default il nome del bean generato coincide con quello del metodo che lo genera, come nel caso testBean dell’esempio. Questo comportamento può essere ridefinito utilizzando il parametro name dell’annotazione @Bean, anche indicando diversi alias, come nel caso dei bean bean1 e bean2 dell’esempio.

L’annotazione @Primary è utilizzata per risolvere l’ambiguità nel caso in cui dal contesto si tenti di recuperare un bean di tipo TestBean che viene generato da entrambe i metodi della classe.

L’annotazione @Bean corrisponde in tutto e per tutto al tag <bean> dell’XML di Spring e di fatto supporta molti degli attributi offerti da tale tag come: init-method, destroy-method, autowiring, lazy-init, dependency-check, depends-on e scope. L’esempio mostra l’uso delle proprietà initMethod e destroyMethod, per la generazione dei bean 1 e 2.

L’ispezione della classe di configurazione avviene utilizzando le classi di bootstrap AnnotationConfigApplicationContext o AnnotationConfigWebApplicationContext per applicazioni web. Il seguente codice una possibile classe di avvio del progetto:

la cui esecuzione mostra il seguente output in consolle:

Ciclo di Vita

Nell’esempio precedente abbiamo visto come, attraverso gli attributi initMethod e destroyMethod sia possibile interagire con il ciclo di vita dei bean. JavaConfig, come il core di Framework, supporta inoltre l’utilizzo delle “Common Annotations” definite nella specificaJSR-250. Per esempio:

JavaConfig supporta inoltre l’uso delle interfacce di callback definite nel framework Spring quali InitializingBean, DisposableBean o Lifecycle i cui rispettivi metodi sono invocati dal container in base al loro Javadoc.

Bean Scope

Come nel caso dell’utilizzo del file XML, anche per i bean definiti attraverso l’annotazione @Bean è possibile controllare lo scope. Allo scopo possiamo utilizzare l’annotazione @Scope specificando lo scope di interesse. Ovviamente sono gestiti dal framework gli scope standard del core di Spring: singleton e prototype, ma anche quelli legati alle request HTTP e gestiti in Spring MVC: request e session.

Codice Sorgente

Il codice sorgente completo di tutti gli esempi presentati può essere scaricato qui javaconfig parte 1.

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!