Approfondimento Dependency Injection

Slides:



Advertisements
Presentazioni simili
Training On Line - CONP. 2 Richiesta Da Menu: Conferimenti ad inizio anno termico > Agosto > Pluriennali > Nuova Richiesta Si accede alla pagina di Richiesta.
Advertisements

Dipartimento di Ingegneria Idraulica e Ambientale - Universita di Pavia 1 Caduta non guidata di un corpo rettangolare in un serbatoio Velocità e rotazione.
1 MeDeC - Centro Demoscopico Metropolitano Provincia di Bologna - per Valutazione su alcuni servizi erogati nel.
TAV.1 Foto n.1 Foto n.2 SCALINATA DI ACCESSO ALL’EREMO DI SANTA CATERINA DEL SASSO DALLA CORTE DELLE CASCINE DEL QUIQUIO Foto n.3 Foto n.4.
II° Circolo Orta Nova (FG)
1 Le s-espressioni. 2 Un nuovo esempio completo: le s-espressioni Sexpr 4 alberi binari (possibilmente vuoti) che hanno sulle foglie atomi (stringhe)
1 Progettazione gerarchica delle s- espressioni, utilizzando lereditarietà
1 Pregnana Milanese Assessorato alle Risorse Economiche Bilancio Preventivo P R O P O S T A.
Interfacce Java.
Capitolo 2 Nozioni fondamentali su Java Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © The McGraw-Hill.
Esercizio 2. Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni di classe.
Frontespizio Economia Monetaria Anno Accademico
1 la competenza alfabetica della popolazione italiana CEDE distribuzione percentuale per livelli.
1 Tavolo del Patto per la crescita intelligente, sostenibile e inclusiva Il ricorso agli ammortizzatori sociali nei territori colpiti dagli eventi sismici.
Implementazione dell algortimo di Viterbi attraverso la soluzione del problema di cammino mi- nimo tramite software specifico. Università degli studi di.
EIE 0607 III / 1 A B P a = 30 P b = 35 t = 2, tc = 1 Questo può essere un equilibrio? No! Politiche di un paese importatore: una tariffa allimportazione.
Esempio: Tombola! Parte seconda.
Unified Modeling Language class C {…} class B extends C {…} Esiste una notazione grafica per mostrare le relazioni di ereditarietà. Object StringC B Tutte.
Sezione: Costruttori Costruttori. Definizione dei costruttori Se per una classe A non scrivo nessun costruttore, il sistema automaticamente crea il costruttore.
prompt> java SumAverage
1 struct Pila { private: int size; int defaultGrowthSize; int marker; int * contenuto; void cresci(int increment); public: Pila(int initialSize) ; Pila();
Programmazione 1 9CFU – TANTE ore
Ufficio Studi UNIONCAMERE TOSCANA 1 Presentazione di Riccardo Perugi Ufficio Studi UNIONCAMERE TOSCANA Firenze, 19 dicembre 2000.
1. Conoscere luso delle collezioni in Java Comprendere le principali caratteristiche nelle varie classi di Collection disponibili Saper individuare quali.
6.6Ordinamento di Vettori Ordinamento di dati –Applicazione computazionale importante –Virtualmente ogni organizzazione deve ordinare dei dati Enormi quantità
1 Implementazione di Linguaggi 2 PARTE 6 Implementazione di Linguaggi 2 PARTE 6 Massimo Ancona DISI Università di Genova Testo: A.V. Aho, R. Sethi, J.D.Ullman.
Master universitario di II livello in Ingegneria delle Infrastrutture e dei Sistemi Ferroviari Anno Accademico 2012/2013 Cultura dimpresa, valutazione.
La partita è molto combattuta perché le due squadre tentano di vincere fino all'ultimo minuto. Era l'ultima giornata del campionato e il risultato era.
Dipartimento di Ingegneria Idraulica e Ambientale - Universita di Pavia 1 Scritte scritte scritte scritte scritte scritte scritte Scritte scritte Titolo.
2000 Prentice Hall, Inc. All rights reserved. 1 Capitolo 6: Classi e astrazione dati 1.Introduzione 2.Definizione delle strutture 3.Accedere ai membri.
Lezione 6 Encoder ottici
Sequence. CREARE UNA SEQUENCE CREATE SEQUENCE nome [INCREMENT BY n] [START WITH n] [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE] [CYCLE | NOCYCLE]
Contatore: esempio di circuito sequenziale
Settimana: 3-7 marzo Orariolunedimartedi Mercoledi 5 Giovedi 6 Venerdi lezione intro alla fis mod DR lezione intro alla fis mod DR.
2 3 4 RISERVATEZZA INTEGRITA DISPONIBILITA 5 6.
Melfi, 1 aprile 2011 – MediaShow 1 Social Network: possibilità di uso consapevole nella didattica Uso, consapevolezza, opportunità, proposte Caterina Policaro.
ISTITUTO COMPRENSIVO TORREGROTTA REPORT DATI QUESTIONARIO Alunni Scuola Primaria Classe V A.S.2012/2013.
CORSO TECNICO R.C.A. ELABORATO PERITALE
1 AOP Sandro Pedrazzini Approfondimento Aspect Oriented Programming (AOP)
JavaScript Lezione 5 Tipizzazione ed operazioni tra tipi diversi Istruzioni di input.
Moduli o Form I Moduli permettono all'utente di immettere informazioni...
Fondamenti di Informatica Corsi di Laurea in Ingegneria Gestionale Canale AL ESERCITAZIONE 6 ARGOMENTI: LAVORARE CON CLASSI METODI DELLISTANZA, COSTRUTTORI.
1 Negozi Nuove idee realizzate per. 2 Negozi 3 4.
ISOIVA (LOCALE) TO ISOIVA (WEB) RIPARTIZIONE INFORMATICA UFFICIO APPLICATIVI AMMINISTRATIVI 13/04/2011 UNIVERSITÀ DEGLI STUDI DI FERRARA 1.
Scheda Ente Ente Privato Ente Pubblico. 2ROL - Richieste On Line.
TECNOLOGIE DELLINFORMAZIONE E DELLA COMUNICAZIONE PER LE AZIENDE Materiale di supporto alla didattica.
14° Workshop – DotNetMarche :: Castelfidardo, 16 Aprile 2010 Introduzione ai framework per IoC / DI e AOP.
1 Guida per linsegnamento nei corsi per il conseguimento del CERTIFICATO DI IDONEITÀ ALLA GUIDA DEL CICLOMOTORE.
Bando Arti Sceniche. Per poter procedere è indispensabile aprire il testo del Bando 2ROL - Richieste On Line.
24 aprile 2002 Avvisi: Risultati 1 o Esonero: (entro) lunedi 27 disponibili nella pag. WEB, ma anche esposti nella bacheca fuori dal corridoio 2 o dente,
LE SAI LE TABELLINE? Mettiti alla prova!.
1 Questionario di soddisfazione del servizio scolastico Anno scolastico 2011/2012 Istogramma- risposte famiglie.
Ese 2 (del 31 Marzo 2004). Mostrare l'evoluzione dello stato (ambiente di classi, heap, pila, System.out) durante la valutazione delle seguenti dichiarazioni.
21 marzo 2002 (ri-)Avvisi: Giovedi 28 marzo la lezione e sospesa. Nuovo indirizzo di Spedire messaggi e esercizi solo.
Test con JUnit. zJUnit è un ambiente di test per programmi Java ySviluppato da Kent Beck É possibile usare JUnit allinterno di Eclipse per eseguire i.
Calendario lezioni ed esercitazioni impartite nell anno accademico 2001/2002 II Semestre Corso di Fisica Sperimentale con Laboratorio Classe di Tecnologie.
1 Simulated multiple inheritance Sandro Pedrazzini Approfondimento Simulated multiple inheritance in Java.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
-17 Aspettative economiche – Europa Settembre 2013 Indicatore > +20 Indicatore 0 a +20 Indicatore 0 a -20 Indicatore < -20 Unione Europea Totale: +6 Indicatore.
Introduzione al linguaggio C. Cos’e’ il C? Il C e’ un linguaggio ad alto livello Un compilatore C prende in input un file contenente codice sorgente C.
Collection & Generics in Java
NO WASTE Progetto continuità scuola primaria scuola secondaria Salorno a.s. 2013_
Numeri Interi senza segno
Mercato del lavoro e condizione giovanile: la crisi si acuisce
JDBC Java DataBase Connectivity SISTEMI ITIS B. CASTELLI Anno Scolastico
1 Acceleratori e Reattori Nucleari Saverio Altieri Dipartimento di Fisica Università degli Studi - Pavia
TRASFORMATA DI FOURIER
IL GIOCO DEL PORTIERE CASISTICA. Caso n. 1 Il portiere nella seguente azione NON commette infrazioni.
Transcript della presentazione:

Approfondimento Dependency Injection

Dependency Injection (DI) Modalità di configurazione di un oggetto, in cui le dipendenze dell’oggetto vengono specificate da entità esterne L’alternativa è che l’oggetto stesso si definisca da solo, al suo interno, le dipendenze Anche chiamata Inversion of Control (IoC), che però ha un significato più esteso (principio del framework in generale)

Esempio Classe che gestisce l’esecuzione del pagamento di un certo ordine (BillingService) Sia la classe responsabile dell’elaborazione dei dati della carta di credito (CreditCardProcessor), sia la classe responsabile di mantenere le informazioni di log (TransactionLog) del pagamento devono poter essere modificate

Esempio (2)

Esempio (2) BillingService carica l’ordine sulla carta di credito. La transazione verrà registrata (log) sia in caso di riuscita, sia in caso di insuccesso public interface IBillingService { Receipt chargeOrder(Order order, CreditCard creditCard); }

Esempio (3) Schema di elaborazione public Receipt chargeOrder(Order order, CreditCard creditCard) { … ChargeResult result = processor.process(order.getAmount(), creditCard); transactionLog.logChargeResult(result); }

Esempio (4) public class BillingService implements IBillingService { public Receipt chargeOrder(Order order, CreditCard creditCard) { ICreditCardProcessor processor = new PaypalCreditCardProcessor(); ITransactionLog transactionLog = new DatabaseTransactionLog(); try { ChargeResult result = processor. process(order.getAmount(), creditCard); transactionLog.logChargeResult(result); return ... } catch (UnreachableException e) { ... }

Esempio (4) Situazione attuale

Commenti Il codice precedente pone problemi di modularità e di test La dipendenza diretta, in compilazione, all’elaboratore di carta di credito significa che ogni chiamata al codice, anche durante il test, esegue una transazione reale sulla carta di credito ICreditCardProcessor processor = new PaypalCreditCardProcessor();

Obiettivo

Factory Una factory permette di separare la classe client (BillingService) dalla classe che implementa un servizio (classi concrete di CreditCardProcessor e TransactionLog) Una factory semplice utilizza alcuni metodi static per stabilire quale implementazione collegare a una data interface

Factory (2) public class CreditCardProcessorFactory { private static ICreditCardProcessor instance; public static void setInstance(ICreditCardProcessor processor) { instance = processor; } public static ICreditCardProcessor getInstance() { if (instance == null) { throw new IllegalStateException("Factory not initialized”); return instance;

Factory (3) public class RealBillingService implements IBillingService { public Receipt chargeOrder(Order order, CreditCard creditCard) { ICreditCardProcessor processor = CreditCardProcessorFactory.getInstance(); ITransactionLog transactionLog = TransactionLogFactory.getInstance(); try { ChargeResult result = processor.process(order.getAmount(), creditCard); transactionLog.logChargeResult(result); return ... } catch (UnreachableException e) { ... }

Factory (4) CreditCardFactory TransactionLogFactory

Factory (5) La scelta dell’implementazione di ICreditCardProcessor e ITransactionLog viene fatta attraverso le factory In questo modo si diminuisce la dipendenza esistente tra BillingService e queste classi L’implementazione dei test diventa più semplice

Unit Test public class BillingServiceTest extends TestCase { private ITransactionLog transactionLog = new InMemoryTransactionLog(); private ICreditCardProcessor processor = new FakeCreditCardProcessor(); public void setUp() { TransactionLogFactory.setInstance(transactionLog); CreditCardProcessorFactory.setInstance(processor); } @Test public void testBilling() { ... public void tearDown() { TransactionLogFactory.setInstance(null); CreditCardProcessorFactory.setInstance(null);

Unit Test (2) ... @Test public void testBilling() { IBillingService billingService = new BillingService(); Order order = new PizzaOrder(100); CreditCard creditCard = new CreditCard("1234", 11, 2010); Receipt receipt = billingService.chargeOrder(order, creditCard); assertTrue(receipt.hasSuccessfulCharge()); assertEquals(100, receipt.getAmountOfCharge()); assertTrue(transactionLog.successfullyLogged()); }

Commenti Codice problematico: le implementazioni vengono praticamente gestite in variabili globali (static) Se il tearDown() dovesse venir interrotto per qualche motivo, avremmo l’implementazione di test che rimane nella factory e potrebbe creare problemi ad altri test Non è possibile eseguire più test in parallelo (variabili static)

Commenti (2) La dipendenza è nascosta nel codice Se per un motivo qualsiasi la factory venisse inizializzata in modo sbagliato, bisognerebbe attendere il primo pagamento per accorgersi del problema La cosa si complicherebbe se il numero di factory dovesse crescere

Dependency Injection Con questo pattern si fa un passo ulteriore verso la separazione tra comportamento e risoluzione della dipendenza BillingService non è più responsabile della risoluzione, perché gli oggetti ICreditCardProcessor e ITransactionLog vengono passati come parametri

Dependency Injection (2) Gli oggetti dipendenti vengono forniti a BillingService dall’esterno, attraverso il costruttore (o attraverso un metodo set()) public BillingService(ICreditCardProcessor creditCardProcessor, ITransactionLog transactionLog) { fCreditCardProcessor = creditCardProcessor; fTransactionLog = transactionLog; }

Dependency Injection (3) public class BillingService implements IBillingService { private ICreditCardProcessor fCreditCardProcessor; private ITransactionLog fTransactionLog; public BillingService(ICreditCardProcessor creditCardProcessor, ITransactionLog transactionLog) { fCreditCardProcessor = creditCardProcessor; fTransactionLog = transactionLog; } public Receipt chargeOrder(Order order, CreditCard creditCard) { try { ChargeResult result= fCreditCardProcessor.process(order.getAmount(), creditCard); fTransactionLog.logChargeResult(result); return ... } catch (Exception e) { ...

Dependency Injection (4) Injector

Commenti Non vengono più usate factory, quindi eliminata la dipendenza tra BilingService e factory Si possono modificare i test, eliminando setUp() e tearDown()

Unit test public class BillingServiceTest { private ICreditCardProcessor processor = new FakeCreditCardProcessor(); private ITransactionLog transactionLog = new InMemoryTransactionLog(); public void testSuccessfulCharge() { Order order = new PizzaOrder(100); CreditCard creditCard = new CreditCard("1234", 11, 2010); IBillingService billingService = new BillingService(processor, transactionLog); Receipt receipt = billingService.chargeOrder(order, creditCard); assertTrue(receipt.hasSuccessfulCharge()); assertEquals(100, receipt.getAmountOfCharge()); assertTrue(transactionLog.successfullyLogged()); }

Commenti Con il passaggio delle dipendenze al costruttore, per ogni nuova dipendenza si deve aggiungere un parametro. In questo modo il compilatore ci può avvertire se nel test ci sono dipendenze da inserire: le dipendenze vengono esposte via API Ora le classi client di IBillingService devono gestire loro le dipendenze

Generalizzazione Si può andare indietro nella catena di dipendenze (classi che dipendono da un’implementazione di IBillingService) Queste classi dovranno accettare IBillingService come parametro Il punto di fermata saranno le classi “top-level”

Generalizzazione (2) Per gestire le dipendenze nelle classi “top-level” è utile usare un framework, che aiuti a ricostruire la gerarchia di dipendenze Ne esistono diversi Bean Container di Spring Guice PicoContainer …

DI con Guice Il pattern DI permette di scrivere codice più modulare e più facilmente testabile Framework come Guice ne facilitano l’implementazione Permettono di associare le interface alle implementazioni necessarie nei vari contesti

DI con Guice (2) La configurazione è specificata in un modulo Guice, una classe che implementa l’interfaccia Module public class BillingModule extends AbstractModule { protected void configure() { bind(ITransactionLog.class).to(DatabaseTransactionLog.class); bind(ICreditCardProcessor.class).to(PaypalCreditCardProcessor.class); bind(IBillingService.class).to(BillingService.class); }

DI con Guice (3) Inserendo @Inject nel costruttore di BillingService, si indica a Guice di passare le dipendenze come specificate nel modulo Nota: non è necessario che le dipendenze vengano specificate con interface. La relazione classe-sottoclasse basta

DI con Guice (4) public class BillingService implements IBillingService { private ICreditCardProcessor fCreditCardProcessor; private ITransactionLog fTransactionLog; @Inject public BillingService(ICreditCardProcessor creditCardProcessor, ITransactionLog transactionLog) { fCreditCardProcessor = creditCardProcessor; fTransactionLog = transactionLog; } public Receipt chargeOrder(Order order, CreditCard creditCard) { ...

DI con Guice (5) Injectable properties: non è necessario prevedere il costruttore per l’inizializzazione public class BillingService implements IBillingService { @Inject private ICreditCardProcessor fCreditCardProcessor; private ITransactionLog fTransactionLog; public Receipt chargeOrder(Order order, CreditCard creditCard) { ... }

Utilizzo public static void main(String[] args) { Injector injector = Guice.createInjector(new BillingModule()); //ricevel’oggetto top level IBillingService billingService = injector.getInstance(IBillingService.class); Receipt receipt = billingService.chargeOrder( new PizzaOrder(100), new CreditCard("1234", 6, 2012)); if (receipt.hasSuccessfulCharge()) { System.out.println("Receipt value: " + receipt.getAmountOfCharge()); } else { System.out.println("Receipt value: " + receipt.getErrorMessage()); }

Altri punti di injection (2) Anche un metodo può essere segnalato con @Inject. Guice chiama questo metodo con l’oggetto associato subito dopo aver chiamato il costruttore Non dev’essere necessariamente un metodo set(), può avere più parametri e non dev’essere per forza pubblico @Inject public void setTransactionLog(ITransactionLog transactionLog){ fTransactionLog = transactionLog; }

Utilizzo di Guice per test (1) public class TestModule extends AbstractModule { protected void configure() { bind(ITransactionLog.class).to(InMemoryTransactionLog.class); bind(ICreditCardProcessor.class).to(FakeCreditCardProcessor.class); bind(IBillingService.class).to(BillingService.class); }

Utilizzo di Guice per test (2) public class BillingServiceWithGuiceTest { private Injector injector = Guice.createInjector(new TestModule()); @Test public void testSuccessfulCharge() { Order order = new PizzaOrder(100); CreditCard creditCard = new CreditCard("1234", 11, 2010); IBillingService billingService = injector.getInstance(IBillingService.class); Receipt receipt = billingService.chargeOrder(order, creditCard); assertTrue(receipt.hasSuccessfulCharge()); assertEquals(100, receipt.getAmountOfCharge()); assertTrue(billingService.getTransactionLog().successfullyLogged()); }

Provider Capita che per la creazione di un oggetto sia necessario più codice che la semplice chiamata al costruttore Normalmente in questi casi scriveremmo un metodo factory, che contenga la chiamata al costruttore, più il codice necessario In Guice il metodo factory viene specificato nel modulo di binding e viene chiamato @Provides method, dal nome dell’annotation da applicare Il binding in configure() va tolto

Metodo @Provides public class BillingModule extends AbstractModule { protected void configure() { // bind(ITransactionLog.class).to(DatabaseTransactionLog.class); ... } @Provides   ITransactionLog provideTransactionLog() {     DatabaseTransactionLog transactionLog = new DatabaseTransactionLog();    transactionLog.setJdbcUrl("jdbc:mysql://localhost/trans");   transactionLog.setThreadPoolSize(30);   return transactionLog;   }

Classe Provider Quando un metodo @Provides inizia ad essere troppo complesso, si può pensare di creare una classe Provider dedicata Guice prevede a questo scopo un’interfaccia Provider che va implementata public interface Provider<T> { T get(); }

Classe Provider (2) Classe responsabile della creazione dell’oggetto ITransactionLog public class DBTransactionProvider implements Provider<ITransactionLog> { public ITransactionLog get() { DatabaseTransactionLog transactionLog = new DatabaseTransactionLog(); transactionLog.setJdbcUrl("jdbc:mysql://localhost/trans");   transactionLog.setThreadPoolSize(30); return transactionLog; }

Classe Provider (3) Binding nella classe di modulo public class BillingModule extends AbstractModule { protected void configure() { bind(ITransactionLog.class). toProvider(DBTransactionProvider.class); ... }

Request Injector Necessario quando all’interno di configure si deve instanziare un oggetto da usare in modo particolare: si crea e si forza il passaggio delle dipendenze ai campi @Inject public class BillingModule extends AbstractModule { protected void configure() { bind(ITransactionLog.class).to(DatabaseTransactionLog.class); bind(ICreditCardProcessor.class).to(PaypalCreditCardProcessor.class); IBillingService billingService = new BillingService(); //necessario forzare injection requestInjection(billingService); … }

Utilizzo contemporaneo di più moduli Più moduli possono essere usati contemporaneamente, se è necessario usare oggetti della stessa classe, ma inizializzati diversamente L’utilizzo di più moduli può essere utile anche a cascata: se un oggetto di un modulo dev’essere creato manualmente all’interno di un provider, se ha dipendenze, queste potrebbero essere specificate all’interno di un secondo modulo.

Utilizzo contemporaneo di più moduli (2) public class DBTransactionProvider implements Provider<ITransactionLog> { public ITransactionLog get() { Injector injector = Guice.createInjector(new DBProductionModule()); ITransactionLog transactionLog = injector.getInstance(ITransactionLog.class); … return transactionLog; }

Scope Per default, Guice restituisce una nuova istanza ogni volta che un oggetto viene richiesto Esempio Ogni colta che si richiede un oggetto ITransactionLog a questo modulo, viene creata una nuova istanza di InMemoryTransactionLog bind(ITransactionLog.class). to(InMemoryTransactionLog.class);

Scope (2) Esistono altri scope, a scelta: Esempio per l’intero ciclo di vita dell’applicazione (@Singleton) per la durata di una sessione (@SessionScoped) per una singola richiesta (@RequestScoped) Esempio Scope configurato durante il binding: bind(ITransactionLog.class). to(InMemoryTransactionLog.class). in(Singleton.class);

Scope (3) Eager singleton Guice prevede la possibilità di specificare oggetti singleton da costruire subito, in anticipo (eagerly) bind(ITransactionLog.class). to(InMemoryTransactionLog.class). asEagerSingleton();

DI con Spring Il Bean Container di Spring risolve le dipendenze durante il caricamento dei singoli oggetti Le dipendenze vengono specificate in un file di configurazione Le dipendenze possono essere specificate, con l’annotation @Autowired Le dipendenze possono essere passate via costruttore o via metodi “set”

Definizione di Bean Le definizioni dei Bean all’interno di una variante di BeanFactory sono rappresentate con oggetti BeanDefinition, contenenti almeno (anche solo implicitamente): nome o id nome della classe elementi di configurazione del comportamento (prototype o singleton, inizializzazione, etc.) argomenti di costruttore e property values da assegnare al bean creato altri bean necessari al bean considerato per eseguire il suo lavoro (dipendenze) <bean id="exampleBean” class="examples.ExampleBean"/>

Singleton I Bean sono definiti per essere installati e attivati in due modalità: singleton o non-singleton (prototype) Altre modalità sono disponibili per ApplicationContext di applicazioni Web (request, session, global session (portlet)) Quando un bean è un singleton, un’unica instanza (shared) del bean viene gestita e creata (per bean e container) Per default i bean sono attivati in modalità singleton

Singleton vs. Prototype Singleton (per bean e contesto)

Singleton vs. Prototype Prototype (istanza)

Proprietà e Dipendenze Le dipendenze possono essere specificate con costruttore o con metodi set <bean id="exampleBean" class="examples.ExampleBean"> <property name="beanOne” ref="anotherExampleBean"/></property> <property name="beanTwo” ref="yetAnotherBean"/></property> <property name="integerProperty"><value>1</value></property> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/> <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

Spring DI (3) Esempio public class ExampleBean { <bean id="exampleBean" class="examples.ExampleBean"> <property name="beanOne” ref=.../></property> <property name="beanTwo” ref=.../></property> <property name="integerProperty"> <value>1</value> </property> </bean> public class ExampleBean { private AnotherBean fBeanOne; private YetAnotherBean fBeanTwo; private int fValue; public void setBeanOne(AnotherBean beanOne) { fBeanOne = beanOne; } public void setBeanTwo(YetAnotherBean beanTwo) { fBeanTwo = beanTwo; public void setIntegerProperty(int value) { fValue = value;

BillingService con Spring Specificare metodi set per RealBillingService public class BillingService implements IBillingService { private ICreditCardProcessor fCreditCardProcessor; private ITransactionLog fTransactionLog; ... public void setCreditCardProcessor(ICreditCardProcessor processor) { fCreditCardProcessor = processor; } public void setTransactionLog(ITransactionLog transactionLog) { fTransactionLog = transactionLog;

BillingService con Spring (2) <bean id=”billingServiceBean" class="examples.BillingService> <property name=”creditCardProcessor” ref="creditCardProcessor"/> <property name=”transactionLog” ref="transactionLog"/> </bean> <bean id=”creditCardProcessor" class="examples.PaypalCrediCardProcessor”/> <bean id=”transactionLog" class="examples.DatabaseTransactionLog”/>

Confronto: Guice e Spring Spring rappresenta un intero stack di elementi per applicazioni enterprise, di cui DI è un tassello Si può comunque usare Spring anche solo per DI (Spring non è un framework “all or nothing”) Guice si concentra invece puramente sugli aspetti di DI (e AOP)

Confronto: Guice e Spring (2) La configurazione Spring (esplicita) avviene in XML, quindi scomoda e poco concisa (tool di sviluppo che offrono una buona integrazione tra Java e XML aiutano comunque a rendere mantenibili le applicazioni) Esiste in Spring una modalità di configurazione “autowired” Guice utilizza annotations, una buona via di mezzo: una modalità concisa, esplicita, mantenibile e supportata dal linguaggio di programmazione